package org.dromara.datacheck.service.impl.jst;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.datacheck.domain.bo.JstAndJDTableDataEntryBo;
import org.dromara.datacheck.domain.bo.jst.ConsignmentBusinessDifferenceBo;
import org.dromara.datacheck.domain.bo.jst.JstSaleOutWarehouseOrderBo;
import org.dromara.datacheck.domain.jd.JdDirectTransferOrder;
import org.dromara.datacheck.domain.jd.JdOtherOutWarehouseOrder;
import org.dromara.datacheck.domain.jd.JdSaleOutWarehouseOrder;
import org.dromara.datacheck.domain.jst.JstSaleOutWarehouseOrder;
import org.dromara.datacheck.domain.jstandjddiff.*;
import org.dromara.datacheck.domain.vo.jd.JdDirectTransferOrderVo;
import org.dromara.datacheck.domain.vo.jd.JdOtherOutWarehouseOrderVo;
import org.dromara.datacheck.domain.vo.jd.JdSaleOutWarehouseOrderVo;
import org.dromara.datacheck.domain.vo.jst.JstSaleOutWarehouseOrderVo;
import org.dromara.datacheck.mapper.jd.JdDirectTransferOrderMapper;
import org.dromara.datacheck.mapper.jd.JdOtherOutWarehouseOrderMapper;
import org.dromara.datacheck.mapper.jd.JdSaleOutWarehouseOrderMapper;
import org.dromara.datacheck.mapper.jst.JstSaleOutWarehouseOrderMapper;
import org.dromara.datacheck.service.jst.IJstSaleOutWarehouseOrderService;
import org.dromara.datacheck.util.MyUtil;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 聚水潭-销售出库单Service业务层处理
 *
 * @author 刘武贵
 * @date 2024-09-08
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class JstSaleOutWarehouseOrderServiceImpl implements IJstSaleOutWarehouseOrderService {

    private final JstSaleOutWarehouseOrderMapper baseMapper;

    /**
     * 金蝶-直接调拨单Service接口
     */
    @Resource
    private JdDirectTransferOrderMapper jdDirectTransferOrderMapper;

    @Resource
    private JdSaleOutWarehouseOrderMapper jdSaleOutWarehouseOrderMapper;

    @Resource
    private JdOtherOutWarehouseOrderMapper jdOtherOutWarehouseOrderMapper;

    /**
     * 查询聚水潭-销售出库单
     *
     * @param id 主键
     * @return 聚水潭-销售出库单
     */
    @Override
    public JstSaleOutWarehouseOrderVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询聚水潭-销售出库单列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 聚水潭-销售出库单分页列表
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageList(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapper(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的聚水潭-销售出库单列表
     *
     * @param bo 查询条件
     * @return 聚水潭-销售出库单列表
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryList(JstSaleOutWarehouseOrderBo bo) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询符合条件的聚水潭-销售出库单列表
     *
     * @param bo 查询条件
     * @return 聚水潭-销售出库单列表
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListNew(JstSaleOutWarehouseOrderBo bo) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperNew(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperNew(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        return lqw;
    }

    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapper(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        return lqw;
    }

    /**
     * 新增聚水潭-销售出库单
     *
     * @param bo 聚水潭-销售出库单
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(JstSaleOutWarehouseOrderBo bo) {
        JstSaleOutWarehouseOrder add = MapstructUtils.convert(bo, JstSaleOutWarehouseOrder.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改聚水潭-销售出库单
     *
     * @param bo 聚水潭-销售出库单
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(JstSaleOutWarehouseOrderBo bo) {
        JstSaleOutWarehouseOrder update = MapstructUtils.convert(bo, JstSaleOutWarehouseOrder.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(JstSaleOutWarehouseOrder entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除聚水潭-销售出库单信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 查询聚水潭-销售出库单列表所有数据
     *
     * @return 聚水潭-销售出库单列表
     */
    @Override
    public List<JstSaleOutWarehouseOrder> queryAll() {
        return baseMapper.selectList(null);
    }

    /**
     * 清空聚水潭-销售出库单列表所有数据
     *
     * @return 聚水潭-销售出库单列表
     */
    @Override
    public Integer deleteAll() {
        return baseMapper.delete(new QueryWrapper<>());
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：寄售-寄售调拨（猫超，进口猫超，京东自营）
     * 业务查询条件：根据shop_name店铺名称为国内货代仓店铺（分销指定）、京东-TYMO京东自营店、天猫-TYMO天猫超市、天猫-TYMO天猫进口超市、,国内零星分销查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName1(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName1(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：寄售-寄售调拨（猫超，进口猫超，京东自营）
     * 业务查询条件：根据shop_name店铺名称为国内货代仓店铺（分销指定）、京东-TYMO京东自营店、天猫-TYMO天猫超市、天猫-TYMO天猫进口超市、,国内零星分销查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName1(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：寄售-寄寄售换货-发货(猫超售后店铺，进口猫超售后店铺)
     * 业务查询条件：根据shop_name店铺名称为天猫超市-售后店铺、天猫进口超市-售后店铺查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName2(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName1(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：寄售-寄寄售换货-发货(猫超售后店铺，进口猫超售后店铺)
     * 业务查询条件：根据shop_name店铺名称为天猫超市-售后店铺、天猫进口超市-售后店铺查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName2(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：分销（山姆）销售-销售
     * 业务查询条件：根据shop_name店铺名称为国内山姆查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName3(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName3(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：分销（山姆）销售-销售
     * 业务查询条件：根据shop_name店铺名称为国内山姆查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName3(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：部门领料-网红达人店
     * 业务查询条件：根据shop_name店铺名称为网红达人店铺查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName4(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName4(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：部门领料-网红达人店
     * 业务查询条件：根据shop_name店铺名称为网红达人店铺查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName4(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：部门领料-展销店铺店发货
     * 业务查询条件：根据shop_name店铺名称为展销样品店铺查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName5(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName5(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：部门领料-展销店铺店发货
     * 业务查询条件：根据shop_name店铺名称为展销样品店铺查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName5(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：部门领料-办公店铺
     * 业务查询条件：根据shop_name店铺名称为办公室店铺查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName6(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName6(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：部门领料-办公店铺
     * 业务查询条件：根据shop_name店铺名称为办公室店铺查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName6(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：部门领料-研发店铺
     * 业务查询条件：根据shop_name店铺名称为研发店铺查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName7(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName7(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：部门领料-研发店铺
     * 业务查询条件：根据shop_name店铺名称为研发店铺查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName7(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：海外出口-海外出口（东莞仓)
     * 业务查询条件：根据shop_name店铺名称为海外备货店铺查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName8(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName8(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：海外出口-海外出口（东莞仓)
     * 业务查询条件：根据shop_name店铺名称为海外备货店铺查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName8(JstSaleOutWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 场景分类：2C销售-销售发货
     * 业务查询条件：根据shop_name店铺名称为除了
     * 国内货代仓店铺（分销指定）、京东-TYMO京东自营店、天猫-TYMO天猫超市、天猫-TYMO天猫进口超市
     * 国内山姆、网红达人店铺、展销样品店铺、办公室店铺、研发店铺、海外备货店铺
     * 天猫超市-售后店铺、天猫进口超市-售后店铺
     * 的所有店铺查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopName9(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopName9(bo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器
     * 场景分类：2C销售-销售发货
     * 业务查询条件：根据shop_name店铺名称为除了
     * 国内货代仓店铺（分销指定）、京东-TYMO京东自营店、天猫-TYMO天猫超市、天猫-TYMO天猫进口超市
     * 国内山姆、网红达人店铺、展销样品店铺、办公室店铺、研发店铺、海外备货店铺
     * 天猫超市-售后店铺、天猫进口超市-售后店铺
     * 的所有店铺查询
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopName9(JstSaleOutWarehouseOrderBo bo) {
        // 需要排除的店铺名称列表
        List<String> excludeShopNames = Arrays.asList(
            "国内货代仓店铺（分销指定）",
            "京东-TYMO京东自营店",
            "天猫-TYMO天猫超市",
            "天猫-TYMO天猫进口超市",
            "国内山姆",
            "网红达人店铺",
            "展销样品店铺",
            "办公室店铺",
            "研发店铺",
            "海外备货店铺",
            "天猫超市-售后店铺",
            "天猫进口超市-售后店铺"
        );

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合，排除特定店铺名称
        lqw.notIn(CollUtil.isNotEmpty(excludeShopNames), JstSaleOutWarehouseOrder::getShopName, excludeShopNames);
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 按日期汇总的统计数据（测试接口1）
     */
    @Override
    public TableDataInfo<Map<String, Object>> jstAndJdSumTest1() throws ParseException {
        // 1、查询两个平台数据
        // 查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "海外备货店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 查询金蝶的数据
        LambdaQueryWrapper<JdDirectTransferOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.eq(JdDirectTransferOrder::getCustomer, "海外备货店铺");
        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdDirectTransferOrderVo> jdDirectTransferOrderList = jdDirectTransferOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getOutboundDeliveryDate))
            .map(JstSaleOutWarehouseOrderVo::getOutboundDeliveryDate)
            .distinct()
            .collect(Collectors.toList());

        // 将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getOutboundDeliveryDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getOutboundDeliveryDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getOutboundDeliveryDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdDirectTransferOrderList.stream()
            .filter(order -> order.getReceiptDate() != null)
            .sorted(Comparator.comparing(JdDirectTransferOrderVo::getReceiptDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getReceiptDate()),
                Collectors.summingInt(JdDirectTransferOrderVo::getAllotQuantity)));

        // 4、合并两个Map，并计算数量之和和差异。按照聚水潭的日期去展示，没有的则为0
        Map<String, Map<String, Object>> combinedMap = new LinkedHashMap<>();
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            combinedMap.put(date, new LinkedHashMap<>() {{
                put("date", date);
                put("jstCount", jstCount);
                put("jdCount", jdCount);
                put("diff", diff);
            }});
        }

        // 构建JSON
        TableDataInfo<Map<String, Object>> result = new TableDataInfo<>();
        result.setRows(combinedMap.values().stream().collect(Collectors.toList()));
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表
     * 按日期汇总的统计数据（测试接口2）
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumTest2() throws ParseException {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "海外备货店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdDirectTransferOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.eq(JdDirectTransferOrder::getCustomer, "海外备货店铺");
        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdDirectTransferOrderVo> jdDirectTransferOrderList = jdDirectTransferOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getOutboundDeliveryDate))
            .map(JstSaleOutWarehouseOrderVo::getOutboundDeliveryDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getOutboundDeliveryDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getOutboundDeliveryDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getOutboundDeliveryDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdDirectTransferOrderList.stream()
            .filter(order -> order.getReceiptDate() != null)
            .sorted(Comparator.comparing(JdDirectTransferOrderVo::getReceiptDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getReceiptDate()),
                Collectors.summingInt(JdDirectTransferOrderVo::getAllotQuantity)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表的差异接口
     * 场景分类：2C销售-销售发货
     * 业务查询条件：根据shop_name店铺名称为除了
     * 国内货代仓店铺（分销指定）、京东-TYMO京东自营店、天猫-TYMO天猫超市、天猫-TYMO天猫进口超市、国内零星分销
     * 国内山姆、网红达人店铺、展销样品店铺、办公室店铺、研发店铺、海外备货店铺
     * 天猫超市-售后店铺、天猫进口超市-售后店铺
     * 的所有店铺查询
     */
    @Override
    public TableDataInfo<JstAndJDDiffDataEntryBo> jstAndJd2cDiff() {
        // 店铺名称集合，排除特定店铺名称
        // 聚水潭需要排除的店铺名称列表
        List<String> jstExcludeShopNames = Arrays.asList(
            "国内货代仓店铺（分销指定）",
            "京东-TYMO京东自营店",
            "天猫-TYMO天猫超市",
            "天猫-TYMO天猫进口超市",
            "国内山姆",
            "网红达人店铺",
            "展销样品店铺",
            "办公室店铺",
            "研发店铺",
            "海外备货店铺",
            "天猫超市-售后店铺",
            "天猫进口超市-售后店铺",
            "国内零星分销"
        );

        // 1、初始化聚水潭和金蝶的差异数据的集合
        List<JstAndJDDiffDataEntryBo> jstAndJDDiffDataEntryBoList = new ArrayList<>();
        JstAndJDDiffDataEntryBo jstAndJDDiffDataEntryBo = new JstAndJDDiffDataEntryBo();

        // 2、查询聚水潭和金蝶的数据，按照2C销售发货的场景分类查询
        // 2-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.notIn(CollUtil.isNotEmpty(jstExcludeShopNames), JstSaleOutWarehouseOrder::getShopName, jstExcludeShopNames);
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 2-2、查询金蝶的数据
        LambdaQueryWrapper<JdDirectTransferOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%FH%");
        lqw2.eq(JdDirectTransferOrder::getCalloutWarehouse, "东莞仓");
        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdDirectTransferOrderVo> jdDirectTransferOrderList = jdDirectTransferOrderMapper.selectVoList(lqw2);

        // 3、处理聚水潭的数据
        // 3-1、先按照日期分组
        // 创建日期格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 使用流和groupingBy进行分组
        Map<String, List<JstSaleOutWarehouseOrderVo>> groupedByDateJst = jstSaleOutWarehouseOrderList.stream()
            .collect(Collectors.groupingBy(
                vo -> vo.getOutboundDeliveryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(formatter)
            ));

        // 3-2、在日期分组的前提下，再按照店铺分组
        Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>> groupedByDateAndShopJst = groupedByDateJst.entrySet().stream()
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                entry -> entry.getValue().stream()
                    .collect(Collectors.groupingBy(JstSaleOutWarehouseOrderVo::getShopName))
            ));

        // 3-3、在店铺分组的前提下，再按照物料编码分组
        Map<String, Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>>> finalGroupedByDateAndShopAndMaterialCodeJst = groupedByDateAndShopJst.entrySet().stream()
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                entry -> entry.getValue().entrySet().stream()
                    .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        shopEntry -> shopEntry.getValue().stream()
                            .filter(vo -> vo.getJdMaterialCode() != null)
                            .collect(Collectors.groupingBy(JstSaleOutWarehouseOrderVo::getJdMaterialCode))
                    )),
                // 解决键冲突的情况
                (oldValue, newValue) -> oldValue,
                // 使用 TreeMap 确保按日期排序
                TreeMap::new
            ));

        // 4、处理金蝶的数据
        // 4-1、在客户分组的前提下，再按照物料编码分组
        Map<String, Map<String, Map<String, List<JdDirectTransferOrderVo>>>> groupedByDateAndCustomerAndMaterialJd = jdDirectTransferOrderList.stream()
            .collect(Collectors.collectingAndThen(
                Collectors.groupingBy(
                    // 第一级分组：按日期分组
                    order -> convertToDate(order.getReceiptDate()),
                    Collectors.groupingBy(
                        // 第二级分组：按客户分组
                        JdDirectTransferOrderVo::getCustomer,
                        Collectors.groupingBy(
                            // 第三级分组：按物料编码分组
                            JdDirectTransferOrderVo::getMaterialCode
                        )
                    )
                ),
                // 将结果转换为 TreeMap 以按日期排序
                result -> new TreeMap<>(result)
            ));

        // 5、分别组装数据
        // 随机生成 ID 的工具类
        Random random = new Random();
        // 5-1、组装聚水潭的数据
        List<JstItem> jstList = assembleDataJst(finalGroupedByDateAndShopAndMaterialCodeJst, random);
        // 5-2、组装聚水潭的数据
        List<KingDeeItem> kingDeeList = assembleDataJd(groupedByDateAndCustomerAndMaterialJd, finalGroupedByDateAndShopAndMaterialCodeJst);
        // 5-3、相互合并数据，目的是为了对齐
        // 按照日期维度合并数据
        mergeDataByOutBountDate(jstList, kingDeeList);
        // 按照出库日期维度合并数据
        mergeDataByShopName(jstList, kingDeeList);
        // 按照物料编码维度合并数据
        mergeDataByMaterialCode(jstList, kingDeeList);

        // 6、最终组装数据
        jstAndJDDiffDataEntryBo.setJstList(jstList);
        jstAndJDDiffDataEntryBo.setKingDeeList(kingDeeList);
        jstAndJDDiffDataEntryBoList.add(jstAndJDDiffDataEntryBo);

        // 构建JSON，构建返回数据
        TableDataInfo<JstAndJDDiffDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDDiffDataEntryBoList);
        result.setMsg("查询成功");
        //
        return result;
    }

    /**
     * 根据分组数据组装JstItem列表
     * 该方法的主要作用是将按日期、店铺和商品码分组的销售出库单数据
     * 组装成树状结构的数据模型（JstItem及其子类），用于后续的数据展示
     *
     * @param groupedData 分组的数据，包含日期、店铺和商品码以及对应的销售出库单列表
     * @param random      随机数生成器，用于在组装过程中生成随机ID
     * @return 组装后的JstItem列表
     */
    public static List<JstItem> assembleDataJst(Map<String, Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>>> groupedData, Random random) {
        List<JstItem> items = new ArrayList<>();

        // 遍历按日期分组的数据
        for (Map.Entry<String, Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>>> dateEntry : groupedData.entrySet()) {
            String date = dateEntry.getKey();

            // 创建JstItem对象并设置基本信息
            JstItem jstItem = new JstItem();
            jstItem.setId(generateRandomId(random));
            jstItem.setDataReplenish(false);
            jstItem.setOutBoundDate(date);


            // 获取当前日期下的按店铺分组的数据
            Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>> shopGroup = dateEntry.getValue();

            // 创建ShopItem列表用于存储店铺信息
            List<ShopItem> shopItems = new ArrayList<>();
            // 遍历按店铺分组的数据
            for (Map.Entry<String, Map<String, List<JstSaleOutWarehouseOrderVo>>> shopEntry : shopGroup.entrySet()) {
                String shopName = shopEntry.getKey();
                int shopSumQuantity = 0;
                // 获取优先级
                Map<String, Integer> priorityMapping = jstAndJdShopPriorityMappingByJst();

                // 根据customerId获取映射后的店铺名称
                Integer priority = priorityMapping.getOrDefault(shopName, 9999);

                // 创建ShopItem对象并设置基本信息
                ShopItem shopItem = new ShopItem();
                shopItem.setId(generateRandomId(random));
                shopItem.setDataReplenish(false);
                shopItem.setShopName(shopName);
                shopItem.setPriority(priority);

                // 获取当前店铺下的按商品码分组的数据
                Map<String, List<JstSaleOutWarehouseOrderVo>> materialGroup = shopEntry.getValue();

                // 创建JstDetail列表用于存储商品信息
                List<JstDetail> details = new ArrayList<>();
                // 遍历按商品码分组的数据
                for (Map.Entry<String, List<JstSaleOutWarehouseOrderVo>> materialEntry : materialGroup.entrySet()) {
                    String materialCode = materialEntry.getKey();
                    // 计算当前商品的总数量
                    int sumQuantity = materialEntry.getValue().stream()
                        .mapToInt(JstSaleOutWarehouseOrderVo::getQuantity)
                        .sum();
                    shopSumQuantity += sumQuantity;

                    // 创建JstDetail对象并设置基本信息
                    JstDetail detail = new JstDetail();
                    detail.setId(generateRandomId(random));
                    detail.setDataReplenish(false);
                    detail.setShopName(shopName);
                    detail.setJstCode(materialCode);
                    detail.setJstSumCount(sumQuantity);

                    // 将当前商品信息添加到详情列表
                    details.add(detail);
                }
                // 设置当前物料的个数
                shopItem.setJstDetailCount(details.size());
                // 设置当前店铺数量总和
                shopItem.setJstSumCount(shopSumQuantity);
                // 按照英文字母升序排序
                Collections.sort(details, Comparator.comparing(JstDetail::getJstCode));
                shopItem.setChildren(details);

                // 将当前店铺信息添加到店铺列表
                shopItems.add(shopItem);
            }

            jstItem.setShopItemCount(shopItems.size());
            // 设置当前日期的总数量
            jstItem.setJstSumCount(shopItems.stream().mapToInt(ShopItem::getJstSumCount).sum());
            // 设置当前日期的店铺列表
            // 按照优先级排序
            Collections.sort(shopItems, Comparator.comparingInt(ShopItem::getPriority));
            jstItem.setChildren(shopItems);
            // 将当前日期的信息添加到JstItem列表
            items.add(jstItem);
        }

        // 返回组装后的JstItem列表
        return items;
    }

    /**
     * 生成一个随机的UUID字符串
     *
     * @param random java.util.Random实例，用于生成随机数此参数未使用，但保留以符合方法签名
     * @return 返回一个新生成的UUID字符串
     */
    private static String generateRandomId(Random random) {
        return UUID.randomUUID().toString();
    }

//    private static String convertToDate(String receiptDate) {
//        DateTimeFormatter originalFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
//        DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//
//        LocalDate localDate = LocalDate.parse(receiptDate, originalFormatter);
//        return localDate.format(targetFormatter);
//    }

    /**
     * 将收据日期字符串从 'yyyy/MM/dd' 格式转换为 'yyyy-MM-dd' 格式
     *
     * @param receiptDate 字符串，表示收据的日期，格式为 'yyyy/MM/dd'
     * @return 格式化后的日期字符串，格式为 'yyyy-MM-dd' 如果输入格式不正确，则返回原样
     */
    private static String convertToDate(String receiptDate) {
        // 使用 replace 方法将 / 替换为 -
        String formattedDate = receiptDate.replace("/", "-");

        // 分割字符串为年、月、日
        String[] parts = formattedDate.split("-");
        if (parts.length == 3) {
            String year = parts[0];
            String month = String.format("%02d", Integer.parseInt(parts[1]));
            String day = String.format("%02d", Integer.parseInt(parts[2]));

            // 重新组合并返回
            return year + "-" + month + "-" + day;
        }

        // 如果输入格式不正确，返回原样
        return formattedDate;
    }

    /**
     * 聚水潭和金蝶的店铺映射Map,key是金蝶的店铺名称，value是聚水潭的店铺名称
     *
     * @return 包含平台与店铺名称映射关系的Map<String, String>
     */
    public static Map<String, String> jstAndJdShopMappingByJd() {
        Map<String, String> shopMapping = new HashMap<>();
        shopMapping.put("TYMO商贸专卖店", "抖音-TYMO商贸专卖店");
        shopMapping.put("TYMO抖音官方旗舰店", "抖音-TYMO旗舰店");
        shopMapping.put("TYMO京东官方旗舰店", "京东-TYMO官方旗舰店");
        shopMapping.put("TYMO快手官方旗舰店", "快手-TYMO官方旗舰店");
        shopMapping.put("美one小程序店", "美one小程序");
        shopMapping.put("TYMO拼多多官方旗舰店", "拼多多-TYMO官方旗舰店");
        shopMapping.put("TYMO淘宝旗舰店", "淘宝-tymo时尚科技");
        shopMapping.put("TYMO天猫海外旗舰店", "天猫-tymo海外旗舰店");
        shopMapping.put("TYMO天猫旗舰店", "天猫-tymo旗舰店");
        shopMapping.put("TYMO小红书旗舰店", "小红书-TYMO旗舰店");
        shopMapping.put("TYMO有赞店", "有赞-TYMO旗舰店");
        shopMapping.put("TYMO微店", "微店-我的小店");
        shopMapping.put("国内货代店铺", "国内货代仓店铺（分销指定）");
        shopMapping.put("海外备货店铺", "海外备货店铺");
        shopMapping.put("TYMO京东自营店", "京东-TYMO京东自营店");
        shopMapping.put("TYMO天猫超市", "天猫-TYMO天猫超市");
        shopMapping.put("TYMO天猫进口超市", "天猫-TYMO天猫进口超市");
        shopMapping.put("山姆会员店", "国内山姆");
        shopMapping.put("猫超寄售售后", "天猫超市-售后店铺");
        shopMapping.put("进口超市售后店铺", "天猫进口超市-售后店铺");
        shopMapping.put("办公店铺", "办公室店铺");
        shopMapping.put("网红达人", "网红达人店铺");
        shopMapping.put("研发店铺", "研发店铺");
        shopMapping.put("展销样品店铺", "展销样品店铺");
        return shopMapping;

    }

    /**
     * 聚水潭和金蝶的店铺映射Map,key是聚水潭的店铺名称，value是金蝶的店铺名称
     *
     * @return 包含平台与店铺名称映射关系的Map<String, String>
     */
    public static Map<String, String> jstAndJdShopMappingByJst() {
        Map<String, String> shopMapping = new HashMap<>();
        shopMapping.put("抖音-TYMO商贸专卖店", "TYMO商贸专卖店");
        shopMapping.put("抖音-TYMO旗舰店", "TYMO抖音官方旗舰店");
        shopMapping.put("京东-TYMO官方旗舰店", "TYMO京东官方旗舰店");
        shopMapping.put("快手-TYMO官方旗舰店", "TYMO快手官方旗舰店");
        shopMapping.put("美one小程序", "美one小程序店");
        shopMapping.put("拼多多-TYMO官方旗舰店", "TYMO拼多多官方旗舰店");
        shopMapping.put("淘宝-tymo时尚科技", "TYMO淘宝旗舰店");
        shopMapping.put("天猫-tymo海外旗舰店", "TYMO天猫海外旗舰店");
        shopMapping.put("天猫-tymo旗舰店", "TYMO天猫旗舰店");
        shopMapping.put("小红书-TYMO旗舰店", "TYMO小红书旗舰店");
        shopMapping.put("有赞-TYMO旗舰店", "TYMO有赞店");
        shopMapping.put("微店-我的小店", "TYMO微店");
        shopMapping.put("国内货代仓店铺（分销指定）", "国内货代店铺");
        shopMapping.put("海外备货店铺", "海外备货店铺");
        shopMapping.put("京东-TYMO京东自营店", "TYMO京东自营店");
        shopMapping.put("天猫-TYMO天猫超市", "TYMO天猫超市");
        shopMapping.put("天猫-TYMO天猫进口超市", "TYMO天猫进口超市");
        shopMapping.put("国内山姆", "山姆会员店");
        shopMapping.put("天猫超市-售后店铺", "猫超寄售售后");
        shopMapping.put("天猫进口超市-售后店铺", "进口超市售后店铺");
        shopMapping.put("办公室店铺", "办公店铺");
        shopMapping.put("网红达人店铺", "网红达人");
        shopMapping.put("研发店铺", "研发店铺");
        shopMapping.put("展销样品店铺", "展销样品店铺");
        return shopMapping;
    }

    /**
     * 聚水潭和金蝶的店铺映射Map,key是金蝶的店铺名称，value是是优先级
     *
     * @return 包含平台与店铺名称映射关系的Map<String, String>
     */
    public static Map<String, Integer> jstAndJdShopPriorityMappingByJd() {
        Map<String, Integer> shopMapping = new HashMap<>();

        // 添加抖音平台的店铺映射
        shopMapping.put("TYMO商贸专卖店", 1);
        shopMapping.put("TYMO抖音官方旗舰店", 2);

        // 添加京东平台的店铺映射
        shopMapping.put("TYMO京东官方旗舰店", 3);

        // 添加快手平台的店铺映射
        shopMapping.put("TYMO快手官方旗舰店", 4);

        // 添加美one小程序的店铺映射
        shopMapping.put("美one小程序店", 5);

        // 添加拼多多平台的店铺映射
        shopMapping.put("TYMO拼多多官方旗舰店", 6);

        // 添加淘宝平台的店铺映射
        shopMapping.put("TYMO淘宝旗舰店", 7);

        // 添加天猫平台的店铺映射
        shopMapping.put("TYMO天猫海外旗舰店", 8);
        shopMapping.put("TYMO天猫旗舰店", 9);

        // 添加小红书平台的店铺映射
        shopMapping.put("TYMO小红书旗舰店", 10);

        // 添加有赞平台的店铺映射
        shopMapping.put("TYMO有赞店", 11);

        // 返回构建好的映射关系
        return shopMapping;

    }


    /**
     * 聚水潭和金蝶的店铺映射Map,key是聚水潭的店铺名称，value是优先级
     *
     * @return 包含平台与店铺名称映射关系的Map<String, String>
     */
    public static Map<String, Integer> jstAndJdShopPriorityMappingByJst() {
        Map<String, Integer> shopMapping = new HashMap<>();

        // 添加抖音平台的店铺映射
        shopMapping.put("抖音-TYMO商贸专卖店", 1);
        shopMapping.put("抖音-TYMO旗舰店", 2);

        // 添加京东平台的店铺映射
        shopMapping.put("京东-TYMO官方旗舰店", 3);

        // 添加快手平台的店铺映射
        shopMapping.put("快手-TYMO官方旗舰店", 4);

        // 添加美one小程序的店铺映射
        shopMapping.put("美one小程序", 5);

        // 添加拼多多平台的店铺映射
        shopMapping.put("拼多多-TYMO官方旗舰店", 6);

        // 添加淘宝平台的店铺映射
        shopMapping.put("淘宝-tymo时尚科技", 7);

        // 添加天猫平台的店铺映射
        shopMapping.put("天猫-tymo海外旗舰店", 8);
        shopMapping.put("天猫-tymo旗舰店", 9);

        // 添加小红书平台的店铺映射
        shopMapping.put("小红书-TYMO旗舰店", 10);

        // 添加有赞平台的店铺映射
        shopMapping.put("有赞-TYMO旗舰店", 11);

        // 返回构建好的映射关系
        return shopMapping;

    }

    /**
     * 根据日期、客户和物料分组的金蝶数据组装成KingDeeItem对象的列表
     *
     * @param groupedByDateAndCustomerAndMaterialJd       金蝶数据，按日期、客户和物料分组
     * @param finalGroupedByDateAndShopAndMaterialCodeJst 聚水潭销售出库订单数据，按日期、店铺和物料代码分组
     * @return KingDeeItem对象的列表，包含组装好的金蝶系统所需数据
     */
    public static List<KingDeeItem> assembleDataJd(
        Map<String, Map<String, Map<String, List<JdDirectTransferOrderVo>>>> groupedByDateAndCustomerAndMaterialJd,
        Map<String, Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>>> finalGroupedByDateAndShopAndMaterialCodeJst) {

        // 初始化金蝶项目列表，用于存储组装后的数据
        List<KingDeeItem> kingDeeItems = new ArrayList<>();
        // 初始化随机数生成器，用于生成随机ID
        Random random = new Random();

        // 遍历金蝶数据，按日期分组
        for (Map.Entry<String, Map<String, Map<String, List<JdDirectTransferOrderVo>>>> dateEntry : groupedByDateAndCustomerAndMaterialJd.entrySet()) {
            String outBoundDate = dateEntry.getKey();
            List<CustomerItem> customerItems = new ArrayList<>();

            // 遍历客户分组
            for (Map.Entry<String, Map<String, List<JdDirectTransferOrderVo>>> customerEntry : dateEntry.getValue().entrySet()) {
                String customerId = customerEntry.getKey();
                List<KingDeeDetail> kingDeeDetails = new ArrayList<>();
                int shopSumQuantity = 0;

                // 遍历物料分组
                Integer priority = null;
                for (Map.Entry<String, List<JdDirectTransferOrderVo>> materialEntry : customerEntry.getValue().entrySet()) {
                    String materialCode = materialEntry.getKey();
                    List<JdDirectTransferOrderVo> jdOrders = materialEntry.getValue();
                    // 获取优先级
                    Map<String, Integer> priorityMapping = jstAndJdShopPriorityMappingByJd();

                    // 根据customerId获取映射后的店铺名称
                    priority = priorityMapping.getOrDefault(customerId, 9999);

                    // 计算当前物料的总数量
                    int kingDeeSumCount = jdOrders.stream().mapToInt(JdDirectTransferOrderVo::getAllotQuantity).sum();
                    shopSumQuantity += kingDeeSumCount;
                    // 计算聚水潭与金蝶之间的差异数量
                    int diffCount = calculateDiffCountJstAndJdByMaterialCode(outBoundDate, customerId, materialCode, finalGroupedByDateAndShopAndMaterialCodeJst, kingDeeSumCount);

                    // 创建并添加明细项
                    KingDeeDetail detail = new KingDeeDetail();
                    detail.setId(generateRandomId(random));
                    detail.setDataReplenish(false);
                    detail.setCustom(customerId);
                    detail.setKingDeeCode(materialCode);
                    detail.setKingDeeSumCount(kingDeeSumCount);
                    detail.setDiffCount(diffCount);
                    kingDeeDetails.add(detail);
                }
                // 按照英文字母升序排序
                Collections.sort(kingDeeDetails, Comparator.comparing(KingDeeDetail::getKingDeeCode));
                int diffCount = calculateDiffCountJstAndJdByCustomer(outBoundDate, customerId, finalGroupedByDateAndShopAndMaterialCodeJst, shopSumQuantity);
                Integer kingDeeDetailCount = kingDeeDetails.size();
                // 创建并添加客户项
                CustomerItem customerItem = new CustomerItem();
                customerItem.setId(generateRandomId(random));
                customerItem.setDataReplenish(false);
                customerItem.setCustom(customerId);
                customerItem.setPriority(priority);
                customerItem.setKingDeeSumCount(shopSumQuantity);
                customerItem.setKingDeeDetailCount(kingDeeDetailCount);
                customerItem.setDiffCount(diffCount);
                customerItem.setChildren(kingDeeDetails);
                customerItems.add(customerItem);
            }

            // 按照优先级排序
            Collections.sort(customerItems, Comparator.comparingInt(CustomerItem::getPriority));
            Integer customerItemCount = customerItems.size();
            Integer sum = customerItems.stream().mapToInt(CustomerItem::getKingDeeSumCount).sum();
            // 创建并添加金蝶项
            KingDeeItem kingDeeItem = new KingDeeItem();
            kingDeeItem.setId(generateRandomId(random));
            kingDeeItem.setDataReplenish(false);
            kingDeeItem.setOutBoundDate(outBoundDate);
            kingDeeItem.setCustomerItemCount(customerItemCount);
            kingDeeItem.setKingDeeSumCount(customerItems.stream().mapToInt(CustomerItem::getKingDeeSumCount).sum());
            int diffCount = calculateDiffCountJstAndJdByOutBoundDate(outBoundDate, finalGroupedByDateAndShopAndMaterialCodeJst, sum);
            kingDeeItem.setDiffCount(diffCount);
            kingDeeItem.setChildren(customerItems);
            kingDeeItems.add(kingDeeItem);
        }

        // 返回组装好的金蝶系统数据列表
        return kingDeeItems;
    }

    /**
     * 计算聚水潭（JST）和金蝶（JD）在指定发货日期的销售出库单数量差异
     * 该方法通过比较聚水潭和金蝶在特定发货日期的销售出库单数量，计算出差异值
     *
     * @param outBoundDate                                销售出库单的发货日期
     * @param finalGroupedByDateAndShopAndMaterialCodeJst 一个映射集合，按照日期、店铺和商品编码分组的聚水潭销售出库单数据
     * @param sum                                         金蝶系统中特定发货日期的销售出库单总数量
     * @return 返回聚水潭和金蝶在指定发货日期的销售出库单数量差异
     */
    private static int calculateDiffCountJstAndJdByOutBoundDate(String outBoundDate, Map<String, Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>>> finalGroupedByDateAndShopAndMaterialCodeJst, Integer sum) {

        // 从聚水潭数据中获取对应的订单数据，利用默认值避免空指针异常
        Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>> dateMap = finalGroupedByDateAndShopAndMaterialCodeJst.getOrDefault(outBoundDate, new HashMap<>());

        // 计算聚水潭的总数量
        int totalJstQuantity = dateMap.values().stream()
            .flatMap(map -> map.values().stream())
            .flatMap(List::stream)
            .mapToInt(JstSaleOutWarehouseOrderVo::getQuantity)
            .sum();

        // 金蝶的总数量已知
        int totalJdQuantity = sum;

        // 计算并返回差异数量
        return totalJstQuantity - totalJdQuantity;
    }

    /**
     * 计算聚水潭(JST)和金蝶(JD)系统之间，针对客户的出库单数量差异
     * 该方法主要用于对聚水潭和金蝶两个系统中的出库单数量进行对比，根据客户ID和出库日期来计算差异量
     *
     * @param outBoundDate                                出库日期，用于定位特定时间的出库单数据
     * @param customerId                                  客户ID，用于店铺映射以确定金蝶中的店铺名称
     * @param finalGroupedByDateAndShopAndMaterialCodeJst 聚水潭数据，按日期、店铺和物料码分组的最终销售出库单数据
     * @param shopSumQuantity                             金蝶店铺汇总的总数量
     * @return 差异数量，即聚水潭系统中的总出库数量减去金蝶系统中的总出库数量
     */
    private static int calculateDiffCountJstAndJdByCustomer(String outBoundDate, String customerId,
                                                            Map<String, Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>>> finalGroupedByDateAndShopAndMaterialCodeJst, int shopSumQuantity) {
        // 获取聚水潭和金蝶的店铺映射
        Map<String, String> shopMapping = jstAndJdShopMappingByJd();

        // 根据customerId获取映射后的店铺名称
        String mappedShopName = shopMapping.getOrDefault(customerId, customerId);

        // 从聚水潭数据中获取对应的订单数据，利用默认值避免空指针异常
        Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>> dateMap = finalGroupedByDateAndShopAndMaterialCodeJst.getOrDefault(outBoundDate, new HashMap<>());
        Map<String, List<JstSaleOutWarehouseOrderVo>> shopMap = dateMap.getOrDefault(mappedShopName, new HashMap<>());

        // 计算差异
        int totalJstQuantity = shopMap.values().stream()
            .flatMap(List::stream)
            .mapToInt(JstSaleOutWarehouseOrderVo::getQuantity)
            .sum();
        // 金蝶的总数量已知
        int totalJdQuantity = shopSumQuantity;

        // 计算并返回差异数量，这里简单地取两个系统数量的差值
        return totalJstQuantity - totalJdQuantity;
    }

    /**
     * 计算聚水潭与金蝶之间的订单数量差异（单个物料的差异）
     * 通过日期、客户ID和物料代码从两个系统的数据中检索相关订单，并计算数量差异。
     *
     * @param outBoundDate                                日期，用于定位订单数据
     * @param customerId                                  客户ID，用于区分不同的客户订单
     * @param materialCode                                物料代码，用于识别特定的物料订单
     * @param finalGroupedByDateAndShopAndMaterialCodeJst 聚水潭销售出库订单数据，按日期、店铺和物料编码分组
     * @param kingDeeSumCount                             金蝶系统中某物料的总数量
     * @return 聚水潭与金蝶之间的订单数量差异的差异值
     */
    private static int calculateDiffCountJstAndJdByMaterialCode(String outBoundDate, String customerId, String materialCode,
                                                                Map<String, Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>>> finalGroupedByDateAndShopAndMaterialCodeJst,
                                                                Integer kingDeeSumCount) {
        // 获取聚水潭和金蝶的店铺映射
        Map<String, String> shopMapping = jstAndJdShopMappingByJd();

        // 根据customerId获取映射后的店铺名称
        String mappedShopName = shopMapping.getOrDefault(customerId, customerId);

        // 从聚水潭数据中获取对应的订单数据，利用默认值避免空指针异常
        Map<String, Map<String, List<JstSaleOutWarehouseOrderVo>>> dateMap = finalGroupedByDateAndShopAndMaterialCodeJst.getOrDefault(outBoundDate, new HashMap<>());
        Map<String, List<JstSaleOutWarehouseOrderVo>> shopMap = dateMap.getOrDefault(mappedShopName, new HashMap<>());
        List<JstSaleOutWarehouseOrderVo> jstOrders = shopMap.getOrDefault(materialCode, new ArrayList<>());

        // 计算差异
        int totalJstQuantity = jstOrders.stream()
            .mapToInt(JstSaleOutWarehouseOrderVo::getQuantity)
            .sum();

        // 计算并返回差异数量，这里简单地取两个系统数量的差值
        return totalJstQuantity - kingDeeSumCount;
    }

    /**
     * 根据出库日期合并聚水潭和金蝶的数据
     * 此方法旨在确保两个数据源在出库日期上一致，缺少的数据会被补全
     *
     * @param jstList     聚水潭物品列表
     * @param kingDeeList 金蝶物品列表
     */
    public static void mergeDataByOutBountDate(List<JstItem> jstList, List<KingDeeItem> kingDeeList) {
        // 1. 按照聚水潭的出库日期，在金蝶数据中没有的数据，进行补齐
        Set<String> jstDates = jstList.stream().map(JstItem::getOutBoundDate).collect(Collectors.toSet());
        Set<String> kingDeeDates = kingDeeList.stream().map(KingDeeItem::getOutBoundDate).collect(Collectors.toSet());

        for (String jstDate : jstDates) {
            if (!kingDeeDates.contains(jstDate)) {
                KingDeeItem newKingDeeItem = createKingDeeItemForJstDate(jstDate, jstList);
                kingDeeList.add(newKingDeeItem);
            }
        }
        // 重新按照日期排序
        kingDeeList.sort(Comparator.comparing(KingDeeItem::getOutBoundDate));

        // 2. 按照金蝶的日期，在聚水潭中没有的数据，进行补齐
        for (String kingDeeDate : kingDeeDates) {
            if (!jstDates.contains(kingDeeDate)) {
                JstItem newJstItem = createJstItemForKingDeeDate(kingDeeDate, kingDeeList);
                jstList.add(newJstItem);
            }
        }
        // 重新按照日期排序
        jstList.sort(Comparator.comparing(JstItem::getOutBoundDate));
    }

    /**
     * 根据给定的JstItem列表和日期创建KingDeeItem对象
     *
     * @param jstDate 字符串类型的日期，用于筛选JstItem的日期
     * @param jstList JstItem的列表，包含所有JstItem对象
     * @return 返回一个新的KingDeeItem对象，该对象根据给定的日期和Jst列表初始化
     */
    private static KingDeeItem createKingDeeItemForJstDate(String jstDate, List<JstItem> jstList) {
        // 创建并初始化一个新的KingDeeItem对象
        KingDeeItem newKingDeeItem = new KingDeeItem();
        newKingDeeItem.setId(UUID.randomUUID().toString());
        newKingDeeItem.setDataReplenish(true);
        newKingDeeItem.setOutBoundDate(jstDate);


        // 计算与给定日期匹配的JstItem的店铺数量总和
        int totalShopItemCount = jstList.stream()
            .filter(item -> item.getOutBoundDate().equals(jstDate))
            .mapToInt(JstItem::getShopItemCount)
            .sum();

        // 设置客户数量为计算得到的店铺数量总和
        newKingDeeItem.setCustomerItemCount(totalShopItemCount);

        // 初始化一个新的CustomerItem列表
        List<CustomerItem> newCustomerItems = new ArrayList<>();
        // 遍历JstItem列表，寻找与给定日期匹配的JstItem
        for (JstItem jstItem : jstList) {
            if (jstItem.getOutBoundDate().equals(jstDate)) {
                newKingDeeItem.setKingDeeSumCount(0);
                newKingDeeItem.setDiffCount(-jstItem.getJstSumCount());
                // 遍历JstItem的子ShopItem列表
                for (ShopItem shop : jstItem.getChildren()) {
                    // 为每个ShopItem创建一个CustomerItem，并添加到列表中
                    CustomerItem newCustomerItem = createCustomerItemForJstShop(shop);
                    newCustomerItems.add(newCustomerItem);
                }
            }
        }

        // 设置新创建的KingDeeItem的子列表为CustomerItem列表
        newKingDeeItem.setChildren(newCustomerItems);
        // 返回新创建的KingDeeItem对象
        return newKingDeeItem;
    }

    /**
     * 为聚水潭店铺创建客户项目条目
     * 此方法主要用于根据聚水潭的店铺信息，生成对应的客户项目条目，包括必要的属性和明细信息
     *
     * @param shop 聚水潭店铺对象，包含店铺名称、优先级以及明细信息等
     * @return 返回生成的客户项目条目对象，包含生成的ID、与金蝶的店铺映射、明细信息等
     */
    private static CustomerItem createCustomerItemForJstShop(ShopItem shop) {
        // 获取聚水潭和金蝶的店铺映射
        Map<String, String> shopMapping = jstAndJdShopMappingByJst();

        // 初始化客户项目条目对象
        CustomerItem newCustomerItem = new CustomerItem();
        // 设置客户项目条目ID为随机UUID
        newCustomerItem.setId(UUID.randomUUID().toString());
        // 设置聚水潭数据存在标志为true
        newCustomerItem.setDataReplenish(true);
        // 设置客户项目条目的店铺信息为聚水潭和金蝶的店铺映射中对应的金蝶店铺代码
        newCustomerItem.setCustom(shopMapping.get(shop.getShopName()));
        // 设置客户项目条目的优先级
        newCustomerItem.setPriority(shop.getPriority());
        // 设置客户项目条目的金蝶汇总数量
        newCustomerItem.setKingDeeSumCount(0);
        // 设置客户项目条目的金蝶明细数量
        newCustomerItem.setKingDeeDetailCount(shop.getJstDetailCount());
        // 设置客户项目条目的差异数量，初始值为负的聚水潭汇总数量，表示未同步的数量差异
        newCustomerItem.setDiffCount(-shop.getJstSumCount());

        // 初始化新的金蝶明细列表
        List<KingDeeDetail> newKingDeeDetails = new ArrayList<>();
        // 遍历聚水潭店铺的明细信息，转换为金蝶明细信息并添加到新的明细列表中
        for (JstDetail jstDetail : shop.getChildren()) {
            KingDeeDetail newKingDeeDetail = createKingDeeDetailForJstDetail(jstDetail);
            newKingDeeDetails.add(newKingDeeDetail);
        }

        // 设置客户项目条目的明细信息为转换后的新明细列表
        newCustomerItem.setChildren(newKingDeeDetails);

        // 返回生成的客户项目条目对象
        return newCustomerItem;
    }


    /**
     * 根据聚水潭明细创建金蝶明细
     *
     * @param jstDetail 聚水潭明细对象，包含聚水潭中的数据详情
     * @return KingDeeDetail 返回新创建的金蝶明细对象
     * <p>
     * 本函数的目的是将聚水潭系统中的明细数据转换为金蝶系统中所需的明细格式
     * 主要涉及店铺映射、数据存在性标记、以及各项数据的转换和设置
     */
    private static KingDeeDetail createKingDeeDetailForJstDetail(JstDetail jstDetail) {
        // 获取聚水潭和金蝶的店铺映射关系，用于后续的店铺代码转换
        Map<String, String> shopMapping = jstAndJdShopMappingByJst();

        // 创建一个新的金蝶明细对象
        KingDeeDetail newKingDeeDetail = new KingDeeDetail();

        // 为新的金蝶明细对象设置唯一的标识符
        newKingDeeDetail.setId(UUID.randomUUID().toString());

        // 标记金蝶明细数据来源于聚水潭，此处设置为true表示数据存在
        newKingDeeDetail.setDataReplenish(true);

        // 根据店铺映射关系，设置金蝶明细中的店铺代码
        newKingDeeDetail.setCustom(shopMapping.get(jstDetail.getShopName()));

        // 将聚水潭明细中的金蝶代码复制到新的金蝶明细中
        newKingDeeDetail.setKingDeeCode(jstDetail.getJstCode());

        // 初始化金蝶明细中的总数量为0，待后续处理
        newKingDeeDetail.setKingDeeSumCount(0);

        // 设置差异数量，此处为聚水潭中的总数量取反，用于后续的差异计算
        newKingDeeDetail.setDiffCount(-jstDetail.getJstSumCount());

        // 返回新创建的金蝶明细对象
        return newKingDeeDetail;
    }


    /**
     * 根据金蝶日期创建JstItem对象
     *
     * @param kingDeeDate 金蝶系统的日期字符串，用于识别和过滤
     * @param kingDeeList 金蝶数据列表，包含多个KingDeeItem对象
     * @return 返回新创建的JstItem对象，包含相关的店铺商品信息
     */
    private static JstItem createJstItemForKingDeeDate(String kingDeeDate, List<KingDeeItem> kingDeeList) {
        // 创建并初始化新的JstItem对象
        JstItem newJstItem = new JstItem();
        newJstItem.setId(UUID.randomUUID().toString()); // 设置唯一标识符
        newJstItem.setDataReplenish(true); // 确认金蝶数据存在
        newJstItem.setOutBoundDate(kingDeeDate); // 设置金蝶系统的日期

        // 计算指定金蝶日期的所有客户商品数量总和
        int totalCustomerItemCount = kingDeeList.stream()
            .filter(item -> item.getOutBoundDate().equals(kingDeeDate))
            .mapToInt(KingDeeItem::getCustomerItemCount)
            .sum();

        // 将计算得到的客户商品数量总和设置到新的JstItem对象中
        newJstItem.setShopItemCount(totalCustomerItemCount);

        // 初始化一个新的店铺商品列表
        List<ShopItem> newShopItems = new ArrayList<>();
        // 遍历金蝶数据列表，寻找与给定金蝶日期匹配的项目
        for (KingDeeItem kingDeeItem : kingDeeList) {
            if (kingDeeItem.getOutBoundDate().equals(kingDeeDate)) {
                // 对每个匹配的项目，进一步处理其所有的子客户商品
                for (CustomerItem customer : kingDeeItem.getChildren()) {
                    // 创建对应的店铺商品对象，并添加到新的店铺商品列表中
                    ShopItem newShopItem = createShopItemForKingDeeCustomer(customer);
                    newShopItems.add(newShopItem);
                }
            }
        }

        // 将新的店铺商品列表设置到新的JstItem对象中
        newJstItem.setChildren(newShopItems);
        // 返回新创建的JstItem对象
        return newJstItem;
    }


    /**
     * 为King Dee客户创建对应的ShopItem对象
     * 此方法专注于将CustomerItem对象转换为适合King Dee客户的ShopItem对象，包括设置必要的属性和关联的明细项
     *
     * @param customer CustomerItem对象，包含客户相关数据
     * @return 返回一个新的ShopItem对象，该对象是为King Dee客户定制的
     */
    private static ShopItem createShopItemForKingDeeCustomer(CustomerItem customer) {
        // 获取King Dee与本地店铺的映射关系
        Map<String, String> shopMapping = jstAndJdShopMappingByJd();

        // 初始化新的ShopItem对象，并设置基础属性
        ShopItem newShopItem = new ShopItem();
        newShopItem.setId(UUID.randomUUID().toString());
        newShopItem.setDataReplenish(true);

        // 根据客户定制化信息设置店铺名称
        newShopItem.setShopName(shopMapping.get(customer.getCustom()));

        // 直接从CustomerItem复制优先级和汇总计数信息
        newShopItem.setPriority(customer.getPriority());
        newShopItem.setJstSumCount(customer.getKingDeeSumCount());
        newShopItem.setJstDetailCount(customer.getKingDeeDetailCount());

        // 创建并关联明细项
        List<JstDetail> newJstDetails = new ArrayList<>();
        for (KingDeeDetail kingDeeDetail : customer.getChildren()) {
            JstDetail newJstDetail = createJstDetailForKingDeeDetail(kingDeeDetail);
            newJstDetails.add(newJstDetail);
        }

        // 设置明细项列表
        newShopItem.setChildren(newJstDetails);

        // 返回构建完成的ShopItem对象
        return newShopItem;
    }


    /**
     * 根据KingDeeDetail对象创建JstDetail对象
     * 此方法用于将KingDee系统的明细数据转换为适用于JST系统的JstDetail对象
     * 主要用于数据同步和系统集成，确保JST系统能够识别和处理从KingDee系统接收到的明细数据
     *
     * @param kingDeeDetail KingDee系统的明细数据对象，包含定制和KingDee编码等信息
     * @return 返回根据KingDeeDetail创建的JstDetail对象，包括新的唯一ID、店铺名称、JST编码和JD数据存在状态
     */
    private static JstDetail createJstDetailForKingDeeDetail(KingDeeDetail kingDeeDetail) {
        // JST和JD店铺编码映射表，根据JD编码获取JST编码
        Map<String, String> shopMapping = jstAndJdShopMappingByJd();

        // 创建新的JstDetail对象
        JstDetail newJstDetail = new JstDetail();

        // 设置新的唯一ID
        newJstDetail.setId(UUID.randomUUID().toString());

        // 设置JD数据存在状态为true
        newJstDetail.setDataReplenish(true);

        // 根据映射表设置店铺名称
        newJstDetail.setShopName(shopMapping.get(kingDeeDetail.getCustom()));

        // 设置JST编码为KingDee编码
        newJstDetail.setJstCode(kingDeeDetail.getKingDeeCode());

        // 初始化JST系统中的数量为0
        newJstDetail.setJstSumCount(0);

        // 返回新创建的JstDetail对象
        return newJstDetail;
    }

    /**
     * 合并聚水潭和金蝶的数据，并进行数据补齐
     *
     * @param jstList     聚水潭的数据列表
     * @param kingDeeList 金蝶的数据列表
     */
    public static void mergeDataByShopName(List<JstItem> jstList, List<KingDeeItem> kingDeeList) {
        // 补齐聚水潭店铺数据
        completeMissingShops(jstList, kingDeeList);

        // 补齐金蝶客户数据
        completeMissingCustomers(jstList, kingDeeList);
    }

    /**
     * 根据聚水潭店铺数据比对，补齐金蝶店铺数据
     *
     * @param jstList     聚水潭的数据列表
     * @param kingDeeList 金蝶的数据列表
     */
    private static void completeMissingShops(List<JstItem> jstList, List<KingDeeItem> kingDeeList) {
        Map<String, String> shopMappingJd = jstAndJdShopMappingByJd();
        Map<String, String> shopMappingJst = jstAndJdShopMappingByJst();
        // 遍历聚水潭项目列表
        for (JstItem jstItem : jstList) {
            // 获取当前聚水潭项目的出库日期
            String jstDate = jstItem.getOutBoundDate();
            // 遍历KingDee项目列表
            for (KingDeeItem kingDeeItem : kingDeeList) {
                // 如果KingDee项目的出库日期与当前JST项目的出库日期相同
                if (kingDeeItem.getOutBoundDate().equals(jstDate)) {
                    // 遍历当前聚水潭项目的店铺列表
                    for (ShopItem shop : jstItem.getChildren()) {
                        // 标记变量，用于判断当前店铺是否已在KingDee项目中存在
                        boolean shopExists = false;
                        // 遍历当前KingDee项目的客户（店铺）列表
                        for (CustomerItem customer : kingDeeItem.getChildren()) {
                            // 如果找到了与当前聚水潭店铺名称匹配的金蝶客户
                            if (StrUtil.isNotBlank(customer.getCustom()) && shopMappingJd.get(customer.getCustom()).equals(shop.getShopName())) {
                                // 将标记设置为true，表示店铺已存在
                                shopExists = true;
                                // 中断当前循环，继续检查下一个JST店铺
                                break;
                            }
                        }
                        // 如果当前店铺在KingDee项目中不存在
                        if (!shopExists) {
                            // 创建一个新的CustomerItem对象来表示这个缺失的店铺
                            CustomerItem newCustomer = new CustomerItem();
                            // 为新店铺生成一个唯一的ID
                            newCustomer.setId(UUID.randomUUID().toString());
                            // 设置JstDataExist为true，表示该店铺在JST数据中存在
                            newCustomer.setDataReplenish(true);
                            // 设置客户的名称为JST店铺的名称
                            newCustomer.setCustom(shopMappingJst.get(shop.getShopName()));
                            // 设置优先级
                            newCustomer.setPriority(shop.getPriority());
                            // 设置KingDeeSumCount为JST店铺的总数量
                            newCustomer.setKingDeeSumCount(0);
                            // 设置KingDeeDetailCount为JST店铺的明细数量
                            newCustomer.setKingDeeDetailCount(shop.getJstDetailCount());
                            newCustomer.setDiffCount(-shop.getJstSumCount());
                            // 初始化明细列表
                            newCustomer.setChildren(new ArrayList<>());

                            // 遍历当前JST店铺的明细列表
                            for (JstDetail detail : shop.getChildren()) {
                                // 创建一个新的KingDeeDetail对象来表示明细信息
                                KingDeeDetail newDetail = new KingDeeDetail();
                                // 为新明细生成一个唯一的ID
                                newDetail.setId(UUID.randomUUID().toString());
                                // 设置JstDataExist为true，表示该明细在JST数据中存在
                                newDetail.setDataReplenish(true);
                                // 设置明细的客户名称为聚水潭店铺的名称
                                newDetail.setCustom(shopMappingJst.get(detail.getShopName()));
                                // 设置明细的物料编码
                                newDetail.setKingDeeCode(detail.getJstCode());
                                // 设置明细的KingDeeSumCount为JST明细的总数量
                                newDetail.setKingDeeSumCount(0);
                                // 设置明细的DiffCount为负的JST明细总数量，表示差异数量
                                newDetail.setDiffCount(-detail.getJstSumCount());
                                // 将新明细添加到新店铺的明细列表中
                                newCustomer.getChildren().add(newDetail);
                            }

                            // 将新店铺添加到金蝶的客户列表中
                            kingDeeItem.getChildren().add(newCustomer);
                        }
                    }
                }
            }
        }
    }

    /**
     * 根据金蝶店铺数据比对，补齐聚水潭店铺数据
     *
     * @param jstList     聚水潭的数据列表
     * @param kingDeeList 金蝶的数据列表
     */
    private static void completeMissingCustomers(List<JstItem> jstList, List<KingDeeItem> kingDeeList) {
        Map<String, String> shopMappingJd = jstAndJdShopMappingByJd();
        Map<String, String> shopMappingJst = jstAndJdShopMappingByJst();
        // 遍历金蝶系统中的每一项数据
        for (KingDeeItem kingDeeItem : kingDeeList) {
            String kingDeeDate = kingDeeItem.getOutBoundDate();
            // 在聚水潭系统中查找相同日期的数据
            for (JstItem jstItem : jstList) {
                if (jstItem.getOutBoundDate().equals(kingDeeDate)) {
                    // 遍历金蝶系统中当前项的每一个客户
                    for (CustomerItem customer : kingDeeItem.getChildren()) {
                        boolean customerExists = false;
                        // 检查此客户是否已经存在于聚水潭系统中
                        for (ShopItem shop : jstItem.getChildren()) {
                            if (StrUtil.isNotBlank(shop.getShopName())) {
                                if (StrUtil.isNotBlank(shop.getShopName()) && shopMappingJst.containsKey(shop.getShopName())) {
                                    if (shopMappingJst.get(shop.getShopName()).equals(customer.getCustom())) {
                                        customerExists = true;
                                        break;
                                    }
                                }
                            }
                        }
                        // 如果此客户在聚水潭系统中不存在，则添加
                        if (!customerExists) {
                            ShopItem newShop = new ShopItem();
                            newShop.setId(UUID.randomUUID().toString());
                            newShop.setDataReplenish(true);
                            newShop.setShopName(customer.getCustom());
                            newShop.setPriority(customer.getPriority());
                            newShop.setJstSumCount(customer.getKingDeeSumCount());
                            newShop.setJstDetailCount(customer.getKingDeeDetailCount());
                            newShop.setChildren(new ArrayList<>());

                            // 为新添加的客户复制明细数据
                            for (KingDeeDetail detail : customer.getChildren()) {
                                JstDetail newDetail = new JstDetail();
                                newDetail.setId(UUID.randomUUID().toString());
                                newDetail.setDataReplenish(true);
                                newDetail.setShopName(shopMappingJd.get(detail.getCustom()));
                                newDetail.setJstCode(detail.getKingDeeCode());
                                newDetail.setJstSumCount(detail.getKingDeeSumCount());
                                newShop.getChildren().add(newDetail);
                            }

                            jstItem.getChildren().add(newShop);
                        }
                    }
                }
            }
        }
    }

    /**
     * 合并聚水潭和金蝶的数据，并进行数据补齐
     *
     * @param jstList     聚水潭的数据列表
     * @param kingDeeList 金蝶的数据列表
     */
    public static void mergeDataByMaterialCode(List<JstItem> jstList, List<KingDeeItem> kingDeeList) {
        // 补齐全物料编码
        completeMissingDetails(jstList, kingDeeList);
    }

    /**
     * 补齐全物料编码
     *
     * @param jstList     聚水潭的数据列表
     * @param kingDeeList 金蝶的数据列表
     */
    private static void completeMissingDetails(List<JstItem> jstList, List<KingDeeItem> kingDeeList) {
        // 创建一个根据金蝶店铺名称映射到聚水潭店铺名称的映射表
        Map<String, String> shopMappingJd = jstAndJdShopMappingByJd();

        // 创建一个根据聚水潭店铺名称映射到金蝶店铺名称的映射表
        Map<String, String> shopMappingJst = jstAndJdShopMappingByJst();

        // 遍历聚水潭商品列表，补齐全聚水潭特有的物料编码
        for (JstItem jstItem : jstList) {
            for (ShopItem shop : jstItem.getChildren()) {
                String jstShopName = shopMappingJst.get(shop.getShopName());
                for (JstDetail jstdetail : shop.getChildren()) {
                    // 在金蝶列表中补充聚水潭缺失的详情
                    completeMissingDetailInKingDee(jstItem, jstShopName, jstdetail, kingDeeList);
                }
            }
        }

        // 遍历金蝶商品列表，补齐金蝶特有的物料编码
        for (KingDeeItem kingDeeItem : kingDeeList) {
            for (CustomerItem customer : kingDeeItem.getChildren()) {
                // 使用映射表获取或确定店铺名称
                String shopName = shopMappingJd.getOrDefault(customer.getCustom(), customer.getCustom());
                for (KingDeeDetail kingDeeDetail : customer.getChildren()) {
                    // 在聚水潭列表中补充金蝶缺失的详情
                    completeMissingDetailInJst(kingDeeItem, shopName, kingDeeDetail, jstList);
                }
            }
        }
    }

    /**
     * 根据聚水潭数据，补齐全金蝶物料编码
     *
     * @param jstItem     当前聚水潭数据项
     * @param jstShopName 聚水潭店铺名称（已经转换好的）
     * @param jstdetail   当前聚水潭物料编码
     * @param kingDeeList 金蝶的数据列表
     */
    private static void completeMissingDetailInKingDee(JstItem jstItem, String jstShopName, JstDetail jstdetail, List<KingDeeItem> kingDeeList) {
        // 获取聚水潭系统中的明细代码
        String jstCode = jstdetail.getJstCode();
        // 遍历金蝶系统中的项列表
        for (KingDeeItem kingDeeItem : kingDeeList) {
            // 比对日期，如果一致则进一步检查
            if (kingDeeItem.getOutBoundDate().equals(jstItem.getOutBoundDate())) {
                // 遍历客户项列表
                for (CustomerItem customer : kingDeeItem.getChildren()) {
                    // 检查客户项中的店铺名称是否和聚水潭系统中的店铺名称一致
                    if (StrUtil.isNotBlank(customer.getCustom()) && customer.getCustom().equals(jstShopName)) {
                        // 标记是否存在相同的明细
                        boolean detailExists = false;
                        // 遍历客户项中的明细列表
                        for (KingDeeDetail detail : customer.getChildren()) {
                            // 如果明细代码一致，标记为明细存在，并跳出循环
                            if (detail.getKingDeeCode().equals(jstCode)) {
                                detailExists = true;
                                break;
                            }
                        }
                        // 如果明细不存在，则创建新的明细并添加到客户项中
                        if (!detailExists) {
                            KingDeeDetail newDetail = new KingDeeDetail();
                            newDetail.setId(UUID.randomUUID().toString());
                            newDetail.setDataReplenish(true);
                            newDetail.setCustom(jstShopName);
                            newDetail.setKingDeeCode(jstdetail.getJstCode());
                            newDetail.setKingDeeSumCount(0);
                            newDetail.setDiffCount(-jstdetail.getJstSumCount());
                            customer.getChildren().add(newDetail);
                        }
                    }
                }
            }
        }
    }

    /**
     * 根据金蝶数据，补齐全聚水潭物料编码
     *
     * @param kingDeeItem   当前金蝶数据项
     * @param shopName      金蝶店铺名称（已经转换好的）
     * @param kingDeeDetail 当前金蝶物料编码
     * @param jstList       聚水潭的数据列表
     */
    private static void completeMissingDetailInJst(KingDeeItem kingDeeItem, String shopName, KingDeeDetail kingDeeDetail, List<JstItem> jstList) {
        // 获取金蝶明细信息中的金蝶代码
        String kingDeeCode = kingDeeDetail.getKingDeeCode();
        // 遍历聚石塔商品列表，寻找匹配的出库单日期
        for (JstItem jstItem : jstList) {
            // 当聚水潭的出库单日期与金蝶的日期匹配时，进一步检查店铺信息
            if (jstItem.getOutBoundDate().equals(kingDeeItem.getOutBoundDate())) {
                // 遍历聚水潭店铺下的店铺信息，寻找匹配的店铺名称
                for (ShopItem shop : jstItem.getChildren()) {
                    // 当店铺名称匹配时，检查该店铺下的明细信息
                    if (StrUtil.isNotBlank(shop.getShopName()) && shop.getShopName().equals(shopName)) {
                        // 标记变量，用于指示当前金蝶明细信息是否已存在于聚石塔明细中
                        boolean detailExists = false;
                        // 遍历店铺下的明细信息，寻找匹配的金蝶的物料编码
                        for (JstDetail detail : shop.getChildren()) {
                            // 如果找到匹配的金蝶物料编码，则标记为明细信息已存在，并结束搜索
                            if (detail.getJstCode().equals(kingDeeCode)) {
                                detailExists = true;
                                break;
                            }
                        }
                        // 如果在聚水潭明细中未找到匹配的金蝶代码，则创建新的明细信息并补充到聚水潭数据中
                        if (!detailExists) {
                            JstDetail newDetail = new JstDetail();
                            newDetail.setId(UUID.randomUUID().toString());
                            newDetail.setDataReplenish(true);
                            newDetail.setShopName(shopName);
                            newDetail.setJstCode(kingDeeDetail.getKingDeeCode());
                            newDetail.setJstSumCount(0);
                            // 将新的明细信息添加到店铺的明细列表中
                            shop.getChildren().add(newDetail);
                        }
                    }
                }
            }
        }
    }


    /**
     * 查询聚水潭-销售出库单列表以及金蝶-直接调拨单（东莞仓->在途）数据汇总（按日期汇总）-2C销售-销售发货
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateBySaleDelivery() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        // 需要排除的店铺名称列表
        List<String> excludeShopNames = Arrays.asList(
            "国内货代仓店铺（分销指定）",
            "京东-TYMO京东自营店",
            "天猫-TYMO天猫超市",
            "天猫-TYMO天猫进口超市",
            "国内山姆",
            "网红达人店铺",
            "展销样品店铺",
            "办公室店铺",
            "研发店铺",
            "海外备货店铺",
            "天猫超市-售后店铺",
            "天猫进口超市-售后店铺",
            "国内零星分销"
        );
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.notIn(CollUtil.isNotEmpty(excludeShopNames), JstSaleOutWarehouseOrder::getShopName, excludeShopNames);
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdDirectTransferOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%FH%");
        lqw2.eq(JdDirectTransferOrder::getCalloutWarehouse, "东莞仓");
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdDirectTransferOrderVo> jdDirectTransferOrderList = jdDirectTransferOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdDirectTransferOrderList.stream()
            .filter(order -> order.getReceiptDate() != null)
            .sorted(Comparator.comparing(JdDirectTransferOrderVo::getReceiptDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getReceiptDate()),
                Collectors.summingInt(JdDirectTransferOrderVo::getAllotQuantity)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表以及金蝶-直接调拨单（东莞仓->寄售仓）数据汇总（按日期汇总）-寄售调拨（猫超，进口猫超，京东自营）
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateByConsignmentAllot() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.in(JstSaleOutWarehouseOrder::getShopName, Arrays.asList("京东-TYMO京东自营店", "天猫-TYMO天猫超市", "天猫-TYMO天猫进口超市", "国内零星分销"));
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdDirectTransferOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
//        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%JS%");
        lqw2.in(JdDirectTransferOrder::getCustomer, Arrays.asList("TYMO京东自营店", "TYMO天猫超市", "TYMO天猫进口超市","零星分销店铺"));
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdDirectTransferOrderVo> jdDirectTransferOrderList = jdDirectTransferOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdDirectTransferOrderList.stream()
            .filter(order -> order.getReceiptDate() != null)
            .sorted(Comparator.comparing(JdDirectTransferOrderVo::getReceiptDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getReceiptDate()),
                Collectors.summingInt(JdDirectTransferOrderVo::getAllotQuantity)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表以及金蝶-直接调拨单（东莞仓->寄售仓）数据汇总（按日期汇总）
     * 场景分类：3、寄售-寄售换货-发货(猫超售后店铺，进口猫超售后店铺)
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateByConsignmentAllotExchangeGoods() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.in(JstSaleOutWarehouseOrder::getShopName, Arrays.asList("天猫超市-售后店铺", "天猫进口超市-售后店铺"));
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdSaleOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
//        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%JS%");
        lqw2.in(JdSaleOutWarehouseOrder::getSaleOutWarehouseOrderCustomer, Arrays.asList("猫超寄售售后", "进口超市售后店铺"));
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdSaleOutWarehouseOrderVo> jdSaleOutWarehouseOrderList = jdSaleOutWarehouseOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getSaleOutWarehouseOrderDate() != null)
            .sorted(Comparator.comparing(JdSaleOutWarehouseOrderVo::getSaleOutWarehouseOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getSaleOutWarehouseOrderDate()),
                Collectors.summingInt(JdSaleOutWarehouseOrderVo::getActualDeliveryNumber)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表以及金蝶-直接调拨单（东莞仓->寄售仓）数据汇总（按日期汇总）
     * 场景分类：4、分销（山姆）销售-销售
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateByDistributionShanMu() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.in(JstSaleOutWarehouseOrder::getShopName, Arrays.asList("国内山姆"));
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdSaleOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
//        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%JS%");
        lqw2.in(JdSaleOutWarehouseOrder::getSaleOutWarehouseOrderCustomer, Arrays.asList("山姆会员店"));
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdSaleOutWarehouseOrderVo> jdSaleOutWarehouseOrderList = jdSaleOutWarehouseOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getSaleOutWarehouseOrderDate() != null)
            .sorted(Comparator.comparing(JdSaleOutWarehouseOrderVo::getSaleOutWarehouseOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getSaleOutWarehouseOrderDate()),
                Collectors.summingInt(JdSaleOutWarehouseOrderVo::getActualDeliveryNumber)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表以及金蝶-其他出库单数据汇总（按日期汇总）
     * 场景分类：5、部门领料-网红达人店
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateByDeptGetMaterial1() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "网红达人店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdOtherOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
//        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%JS%");
        lqw2.eq(JdOtherOutWarehouseOrder::getJdOtherOutWarehouseOrderCustomer, "网红达人");
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdOtherOutWarehouseOrderVo> jdOtherOutWarehouseOrderList = jdOtherOutWarehouseOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdOtherOutWarehouseOrderList.stream()
            .filter(order -> order.getOrderDate() != null)
            .sorted(Comparator.comparing(JdOtherOutWarehouseOrderVo::getOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getOrderDate()),
                Collectors.summingInt(JdOtherOutWarehouseOrderVo::getActualDeliveryNumber)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表以及金蝶-其他出库单数据汇总（按日期汇总）
     * 场景分类：5、部门领料-展销店铺店发货
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateByDeptGetMaterial2() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "展销样品店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdOtherOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
//        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%JS%");
        lqw2.eq(JdOtherOutWarehouseOrder::getJdOtherOutWarehouseOrderCustomer, "展销样品店铺");
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdOtherOutWarehouseOrderVo> jdOtherOutWarehouseOrderList = jdOtherOutWarehouseOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdOtherOutWarehouseOrderList.stream()
            .filter(order -> order.getOrderDate() != null)
            .sorted(Comparator.comparing(JdOtherOutWarehouseOrderVo::getOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getOrderDate()),
                Collectors.summingInt(JdOtherOutWarehouseOrderVo::getActualDeliveryNumber)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表以及金蝶-其他出库单数据汇总（按日期汇总）
     * 场景分类：5、部门领料-办公店铺
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateByDeptGetMaterial3() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "办公室店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdOtherOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
//        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%JS%");
        lqw2.eq(JdOtherOutWarehouseOrder::getJdOtherOutWarehouseOrderCustomer, "办公店铺");
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdOtherOutWarehouseOrderVo> jdOtherOutWarehouseOrderList = jdOtherOutWarehouseOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdOtherOutWarehouseOrderList.stream()
            .filter(order -> order.getOrderDate() != null)
            .sorted(Comparator.comparing(JdOtherOutWarehouseOrderVo::getOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getOrderDate()),
                Collectors.summingInt(JdOtherOutWarehouseOrderVo::getActualDeliveryNumber)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表以及金蝶-其他出库单数据汇总（按日期汇总）
     * 场景分类：5、部门领料-研发店铺
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateByDeptGetMaterial4() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "研发店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdOtherOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
//        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%JS%");
        lqw2.eq(JdOtherOutWarehouseOrder::getJdOtherOutWarehouseOrderCustomer, "研发店铺");
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdOtherOutWarehouseOrderVo> jdOtherOutWarehouseOrderList = jdOtherOutWarehouseOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdOtherOutWarehouseOrderList.stream()
            .filter(order -> order.getOrderDate() != null)
            .sorted(Comparator.comparing(JdOtherOutWarehouseOrderVo::getOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getOrderDate()),
                Collectors.summingInt(JdOtherOutWarehouseOrderVo::getActualDeliveryNumber)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表以及金蝶-直接调拨单(东莞仓->待报关在途仓）汇总（按日期汇总）
     * 场景分类：9、海外出口-海外出口（东莞仓)
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDateByOverSeasExport() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList = new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        // 店铺名称集合，排除特定店铺名称
        lqw1.in(JstSaleOutWarehouseOrder::getShopName, Arrays.asList("国内货代仓店铺（分销指定）","海外备货店铺" ));
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdDirectTransferOrder> lqw2 = Wrappers.lambdaQuery();
        // 继续处理其他字符串类型的查询条件
//        lqw2.like(JdDirectTransferOrder::getReceiptNumber, "%JS%");
        lqw2.in(JdDirectTransferOrder::getCustomer, Arrays.asList("国内货代店铺","海外备货店铺" ));
//        lqw2.eq(JdDirectTransferOrder::getReceiptStatus, "已审核");
        List<JdDirectTransferOrderVo> jdDirectTransferOrderList = jdDirectTransferOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstSaleOutWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .map(JstSaleOutWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstSaleOutWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstSaleOutWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstSaleOutWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdDirectTransferOrderList.stream()
            .filter(order -> order.getReceiptDate() != null)
            .sorted(Comparator.comparing(JdDirectTransferOrderVo::getReceiptDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getReceiptDate()),
                Collectors.summingInt(JdDirectTransferOrderVo::getAllotQuantity)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i < formattedDateList.size() + 1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-销售出库单列表（金蝶缺少的数据）
     * 场景分类：3、寄售-寄售调拨（猫超，进口猫超，京东自营）
     * 业务查询条件：根据shop_name店铺名称为国内货代仓店铺（分销指定）、京东-TYMO京东自营店、天猫-TYMO天猫超市、天猫-TYMO天猫进口超市、零星分销店铺查询
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopNameByJdDeficiency1(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算3、寄售-寄售调拨（猫超，进口猫超，京东自营）场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference1();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopNameByJdDeficiency1(bo, consignmentBusinessDifferenceBo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 计算3、寄售-寄售调拨（猫超，进口猫超，京东自营）场景业务差异数据
     */
    private ConsignmentBusinessDifferenceBo calculateConsignmentBusinessDifference1() {
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // List<Map<key内部订单号 value物料编码>>集合，最终组成要去查询金蝶缺少数据的条件
        List<Map<String, List<String>>> orderMaterialMap = new ArrayList<>();
        // key内部订单号 value聚水潭销售出库单集合
        Map<String, List<JstSaleOutWarehouseOrderVo>> groupedByInnerOrderNumber1 = new HashMap<>();
        // key内部订单号 value聚水潭销售出库单对应的物料编码集合
        Map<String, List<String>> groupedByInnerOrderNumber2 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单集合
        Map<String, List<JdDirectTransferOrderVo>> groupedByReceiptNumber1 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单的物料编码集合
        Map<String, List<String>> groupedByReceiptNumber2 = new HashMap<>();
        // 聚水潭日期
        Set<String> jstOrderDateList = new HashSet<>();

        // 1、查询聚水潭销售出库单，并且按照内部订单号分组
        // 一个内部订单号对应多条聚水潭销售出库单。形如<String,List<JstSaleOutWarehouseOrder>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单集合
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        lqw1.in(JstSaleOutWarehouseOrder::getShopName, Arrays.asList("京东-TYMO京东自营店", "天猫-TYMO天猫超市", "天猫-TYMO天猫进口超市", "国内零星分销"));
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            // 根据 innerOrderNumber 分组
            groupedByInnerOrderNumber1 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(JstSaleOutWarehouseOrderVo::getInnerOrderNumber));

            // 第二次分组，形如Map<String,List<String>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单物料编码集合
            // 根据 innerOrderNumber 分组，并提取 jdMaterialCode
            groupedByInnerOrderNumber2 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(
                    JstSaleOutWarehouseOrderVo::getInnerOrderNumber,
                    Collectors.mapping(JstSaleOutWarehouseOrderVo::getJdMaterialCode, Collectors.toList())
                ));

        }

        // 2、查询金蝶直接调拨单，并且按照单据编号分组
        LambdaQueryWrapper<JdDirectTransferOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.in(JdDirectTransferOrder::getCustomer, Arrays.asList("TYMO京东自营店", "TYMO天猫超市", "TYMO天猫进口超市", "零星分销店铺"));
        List<JdDirectTransferOrderVo> jdDirectTransferOrderList = jdDirectTransferOrderMapper.selectVoList(lqw2);
        if (CollUtil.isNotEmpty(jdDirectTransferOrderList)) {
            // 单据编号形如2057362-001-JS的，需要把-001-JS这部分内容去掉，一个内部订单号对应多条金蝶直接调拨单
            // 形如<String,List<JdDirectTransferOrder>>，key是单据编号， value是该单据编号对应的金蝶直接调拨单集合
            groupedByReceiptNumber1 = jdDirectTransferOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                    String receiptNumber = order.getReceiptNumber();
                    if (receiptNumber != null && receiptNumber.contains("-")) {
                        return receiptNumber.split("-")[0];
                    }
                    return receiptNumber;
                }));
            // 第二次分组，形如Map<String,List<String>>，key是单据编号， value是该单据编号对应的金蝶直接调拨单物料编码集合
            groupedByReceiptNumber2 = jdDirectTransferOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                        String receiptNumber = order.getReceiptNumber();
                        if (receiptNumber != null && receiptNumber.contains("-")) {
                            return receiptNumber.split("-")[0];
                        }
                        return receiptNumber;
                    },
                    Collectors.mapping(JdDirectTransferOrderVo::getMaterialCode, Collectors.toList())));

        }

        if (CollUtil.isNotEmpty(groupedByInnerOrderNumber2) && CollUtil.isNotEmpty(groupedByReceiptNumber2)) {
            // 3、数据比较，两次比较均以聚水潭的为准，比对出缺少的数据，组装多个Map<String, List<String>，添加进List<Map<String, List<String>>> orderMaterialMap中
            // 3-1、第一次比较，比较出金蝶不存在的内部订单号，其对应的物料编码需要去第1步中的聚水潭分组数据查询，组装多个Map<String, List<String>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            Set<String> jstInnerOrderNumbers = groupedByInnerOrderNumber1.keySet();
            Set<String> jdReceiptNumbers = groupedByReceiptNumber1.keySet();

            // 金蝶中不存在的内部订单号
            Set<String> missingInnerOrderNumbers = jstInnerOrderNumbers.stream()
                .filter(innerOrderNumber -> !jdReceiptNumbers.contains(innerOrderNumber))
                .collect(Collectors.toSet());

            for (String missingInnerOrderNumber : missingInnerOrderNumbers) {
                List<String> materialCodes = groupedByInnerOrderNumber2.get(missingInnerOrderNumber);
                if (materialCodes != null) {
                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                    missingOrderMaterialMap.put(missingInnerOrderNumber, materialCodes);
                    orderMaterialMap.add(missingOrderMaterialMap);
                }
            }

            // 3-2、第二次比较，内部订单号相同的情况下，比对缺少的物料编码，组装多个Map<String, List<String>>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            for (String innerOrderNumber : jstInnerOrderNumbers) {
                if (jdReceiptNumbers.contains(innerOrderNumber)) {
                    List<String> jstMaterialCodes = groupedByInnerOrderNumber2.get(innerOrderNumber);
                    List<String> jdMaterialCodes = groupedByReceiptNumber2.get(innerOrderNumber);

                    if (jstMaterialCodes != null && jdMaterialCodes != null) {
                        // 获取聚水潭和金蝶的日期
                        List<String> jstOrderDates = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                            .map(JstSaleOutWarehouseOrderVo::getCompareDateToJd)
                            .distinct()
                            .collect(Collectors.toList());
                        List<String> jdOrderDates = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                            .map(JdDirectTransferOrderVo::getReceiptDate)
                            .distinct()
                            .collect(Collectors.toList());

                        // 比较日期
                        for (String jstOrderDate : jstOrderDates) {
                            if (!jdOrderDates.contains(jstOrderDate)) {
                                // 金蝶中不存在该日期的内部订单号
                                Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                missingOrderMaterialMap.put(innerOrderNumber, jstMaterialCodes);
                                jstOrderDateList.add(jstOrderDate);
                                orderMaterialMap.add(missingOrderMaterialMap);
                            } else {
                                // 日期相同的情况下，比对缺少的物料编码
                                List<String> jstMaterialCodesForDate = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getCompareDateToJd().equals(jstOrderDate))
                                    .map(JstSaleOutWarehouseOrderVo::getJdMaterialCode)
                                    .collect(Collectors.toList());
                                List<String> jdMaterialCodesForDate = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getReceiptDate().equals(jstOrderDate))
                                    .map(JdDirectTransferOrderVo::getMaterialCode)
                                    .collect(Collectors.toList());

                                List<String> missingMaterialCodes = jstMaterialCodesForDate.stream()
                                    .filter(materialCode -> !jdMaterialCodesForDate.contains(materialCode))
                                    .collect(Collectors.toList());

                                if (!missingMaterialCodes.isEmpty()) {
                                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                    missingOrderMaterialMap.put(innerOrderNumber, missingMaterialCodes);
                                    orderMaterialMap.add(missingOrderMaterialMap);
                                }
                                jstOrderDateList.add(jstOrderDate);
                            }
                        }
                    }
                }
            }
        }
        consignmentBusinessDifferenceBo.setOrderMaterialMap(orderMaterialMap);
        consignmentBusinessDifferenceBo.setJstOrderDateList(jstOrderDateList);
        return consignmentBusinessDifferenceBo;

    }

    /**
     * 构建查询包装器（金蝶缺少的数据）
     * 场景分类：3、寄售-寄售调拨（猫超，进口猫超，京东自营）
     * 业务查询条件：根据shop_name店铺名称为国内货代仓店铺（分销指定）、京东-TYMO京东自营店、天猫-TYMO天猫超市、天猫-TYMO天猫进口超市查询
     *
     * @param bo                              业务对象，包含查询参数
     * @param consignmentBusinessDifferenceBo 计算寄售业务差异bo对象
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopNameByJdDeficiency1(JstSaleOutWarehouseOrderBo bo,
                                                                                                    ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }

        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }


        return lqw;
    }

    /**
     * 查询符合条件的聚水潭-销售出库单列表（3、寄售-寄售调拨（猫超，进口猫超，京东自营）的差异数据）
     *
     * @param bo 查询条件
     * @return 聚水潭-销售出库单列表
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListConsignmentBusinessDifference1(JstSaleOutWarehouseOrderBo bo) {
        // 计算3、寄售-寄售调拨（猫超，进口猫超，京东自营）场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference1();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperConsignmentBusinessDifference1(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }


    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperConsignmentBusinessDifference1(JstSaleOutWarehouseOrderBo bo, ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }

        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表（金蝶缺少的数据）
     * 场景分类：3、寄售-寄售换货-发货(猫超售后店铺，进口猫超售后店铺)
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopNameByJdDeficiency2(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算寄售-寄售换货-发货(猫超售后店铺，进口猫超售后店铺)场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference2();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopNameByJdDeficiency2(bo, consignmentBusinessDifferenceBo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    private ConsignmentBusinessDifferenceBo calculateConsignmentBusinessDifference2() {
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // 聚水潭所有内部订单号
        List<String> jstInnerOrderNumberList = new ArrayList<>();
        // 金蝶所有单据编号
        List<String> jdOrderNumberList = new ArrayList<>();
        // 1、查询聚水潭销售出库单，取出所有内部订单号
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        lqw1.in(JstSaleOutWarehouseOrder::getShopName, Arrays.asList("天猫超市-售后店铺", "天猫进口超市-售后店铺"));
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            jstInnerOrderNumberList = jstSaleOutWarehouseOrderList.stream().map(JstSaleOutWarehouseOrderVo::getInnerOrderNumber).toList();
        }

        // 2、查询金蝶销售出库单，取出所有单据编号分组
        LambdaQueryWrapper<JdSaleOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.in(JdSaleOutWarehouseOrder::getSaleOutWarehouseOrderCustomer, Arrays.asList("猫超寄售售后", "进口超市售后店铺"));
        List<JdSaleOutWarehouseOrderVo> jdSaleOutWarehouseOrderList = jdSaleOutWarehouseOrderMapper.selectVoList(lqw2);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            // 单据编号形如1970462-001-FX的，需要把-001-FX这部分内容去掉
            jdOrderNumberList = jdSaleOutWarehouseOrderList.stream()
                .map(JdSaleOutWarehouseOrderVo::getSaleOutWarehouseOrderNumber)
                .map(orderNumber -> orderNumber.split("-")[0])
                .toList();
        }

        // 3、数据比较以聚水潭的入仓单号为准，比较缺少的单据编号组成新的List<String>
        List<String> finalJdOrderNumberList = jdOrderNumberList;
        List<String> missingOrderNumbers = jstInnerOrderNumberList.stream()
            .filter(jstOrderNumber -> !finalJdOrderNumberList.contains(jstOrderNumber))
            .collect(Collectors.toList());

        // 将缺失的单据编号设置到 ConsignmentBusinessDifferenceBo 对象中
        consignmentBusinessDifferenceBo.setReceiptNumberList(missingOrderNumbers);

        return consignmentBusinessDifferenceBo;
    }

    /**
     * 构建查询包装器（金蝶缺少的数据）
     * 场景分类：4、分销（山姆）销售-销售
     *
     * @param bo                              业务对象，包含查询参数
     * @param consignmentBusinessDifferenceBo 计算寄售业务差异bo对象
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopNameByJdDeficiency2(JstSaleOutWarehouseOrderBo bo,
                                                                                                    ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.in(JstSaleOutWarehouseOrder::getInnerOrderNumber, consignmentBusinessDifferenceBo.getReceiptNumberList());
        }
        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, 0);
        }

        return lqw;
    }

    /**
     * 导出聚水潭-销售出库单列表（导出3、寄售-寄售换货-发货(猫超售后店铺，进口猫超售后店铺)的差异数据）
     *
     * @param bo
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListConsignmentBusinessDifference2(JstSaleOutWarehouseOrderBo bo) {
        // 计算3、寄售-寄售换货-发货(猫超售后店铺，进口猫超售后店铺)场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference2();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperConsignmentBusinessDifference2(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }


    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperConsignmentBusinessDifference2(JstSaleOutWarehouseOrderBo bo, ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.in(JstSaleOutWarehouseOrder::getInnerOrderNumber, consignmentBusinessDifferenceBo.getReceiptNumberList());
        }
        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, 0);
        }
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表（金蝶缺少的数据）
     * 场景分类：4、分销（山姆）销售-销售
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopNameByJdDeficiency3(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算寄售-寄售换货-发货(猫超售后店铺，进口猫超售后店铺)场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference3();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopNameByJdDeficiency3(bo, consignmentBusinessDifferenceBo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    private ConsignmentBusinessDifferenceBo calculateConsignmentBusinessDifference3() {
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // 聚水潭所有内部订单号
        List<String> jstInnerOrderNumberList = new ArrayList<>();
        // 金蝶所有单据编号
        List<String> jdOrderNumberList = new ArrayList<>();
        // 1、查询聚水潭销售出库单，取出所有内部订单号
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "国内山姆");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            jstInnerOrderNumberList = jstSaleOutWarehouseOrderList.stream().map(JstSaleOutWarehouseOrderVo::getInnerOrderNumber).toList();
        }

        // 2、查询金蝶销售出库单，取出所有单据编号分组
        LambdaQueryWrapper<JdSaleOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.eq(JdSaleOutWarehouseOrder::getSaleOutWarehouseOrderCustomer, "山姆会员店");
        List<JdSaleOutWarehouseOrderVo> jdSaleOutWarehouseOrderList = jdSaleOutWarehouseOrderMapper.selectVoList(lqw2);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            // 单据编号形如1970462-001-FX的，需要把-001-FX这部分内容去掉
            jdOrderNumberList = jdSaleOutWarehouseOrderList.stream()
                .map(JdSaleOutWarehouseOrderVo::getSaleOutWarehouseOrderNumber)
                .map(orderNumber -> orderNumber.split("-")[0])
                .toList();
        }

        // 3、数据比较以聚水潭的入仓单号为准，比较缺少的单据编号组成新的List<String>
        List<String> finalJdOrderNumberList = jdOrderNumberList;
        List<String> missingOrderNumbers = jstInnerOrderNumberList.stream()
            .filter(jstOrderNumber -> !finalJdOrderNumberList.contains(jstOrderNumber))
            .collect(Collectors.toList());

        // 将缺失的单据编号设置到 ConsignmentBusinessDifferenceBo 对象中
        consignmentBusinessDifferenceBo.setReceiptNumberList(missingOrderNumbers);

        return consignmentBusinessDifferenceBo;
    }

    /**
     * 构建查询包装器（金蝶缺少的数据）
     * 场景分类：4、分销（山姆）销售-销售
     *
     * @param bo                              业务对象，包含查询参数
     * @param consignmentBusinessDifferenceBo 计算寄售业务差异bo对象
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopNameByJdDeficiency3(JstSaleOutWarehouseOrderBo bo,
                                                                                                    ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.in(JstSaleOutWarehouseOrder::getInnerOrderNumber, consignmentBusinessDifferenceBo.getReceiptNumberList());
        }
        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, 0);
        }

        return lqw;
    }

    /**
     * 导出聚水潭-销售出库单列表（导出4、分销（山姆）销售-销售的差异数据）
     *
     * @param bo
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListConsignmentBusinessDifference3(JstSaleOutWarehouseOrderBo bo) {
        // 计算3、寄售-寄售换货-发货(猫超售后店铺，进口猫超售后店铺)场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference3();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperConsignmentBusinessDifference3(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperConsignmentBusinessDifference3(JstSaleOutWarehouseOrderBo bo, ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.in(JstSaleOutWarehouseOrder::getInnerOrderNumber, consignmentBusinessDifferenceBo.getReceiptNumberList());
        }
        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, 0);
        }
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表（金蝶缺少的数据）
     * 场景分类：5、部门领料-网红达人店
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopNameByJdDeficiency4(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算5、部门领料-网红达人店场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference4();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopNameByJdDeficiency4(bo, consignmentBusinessDifferenceBo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    /**
     * 计算5、部门领料-网红达人店场景业务差异数据
     */
    private ConsignmentBusinessDifferenceBo calculateConsignmentBusinessDifference4() {
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // List<Map<key内部订单号 value物料编码>>集合，最终组成要去查询金蝶缺少数据的条件
        List<Map<String, List<String>>> orderMaterialMap = new ArrayList<>();
        // key内部订单号 value聚水潭销售出库单集合
        Map<String, List<JstSaleOutWarehouseOrderVo>> groupedByInnerOrderNumber1 = new HashMap<>();
        // key内部订单号 value聚水潭销售出库单对应的物料编码集合
        Map<String, List<String>> groupedByInnerOrderNumber2 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单集合
        Map<String, List<JdOtherOutWarehouseOrderVo>> groupedByReceiptNumber1 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单的物料编码集合
        Map<String, List<String>> groupedByReceiptNumber2 = new HashMap<>();
        // 聚水潭日期
        Set<String> jstOrderDateList = new HashSet<>();

        // 1、查询聚水潭销售出库单，并且按照内部订单号分组
        // 一个内部订单号对应多条聚水潭销售出库单。形如<String,List<JstSaleOutWarehouseOrder>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单集合
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "网红达人店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            // 根据 innerOrderNumber 分组
            groupedByInnerOrderNumber1 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(JstSaleOutWarehouseOrderVo::getInnerOrderNumber));

            // 第二次分组，形如Map<String,List<String>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单物料编码集合
            // 根据 innerOrderNumber 分组，并提取 jdMaterialCode
            groupedByInnerOrderNumber2 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(
                    JstSaleOutWarehouseOrderVo::getInnerOrderNumber,
                    Collectors.mapping(JstSaleOutWarehouseOrderVo::getJdMaterialCode, Collectors.toList())
                ));

        }

        // 2、查询金蝶其他出库单，并且按照单据编号分组
        LambdaQueryWrapper<JdOtherOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.eq(JdOtherOutWarehouseOrder::getJdOtherOutWarehouseOrderCustomer, "网红达人");
        List<JdOtherOutWarehouseOrderVo> jdOtherOutWarehouseOrderList = jdOtherOutWarehouseOrderMapper.selectVoList(lqw2);
        if (CollUtil.isNotEmpty(jdOtherOutWarehouseOrderList)) {
            // 单据编号形如2057362-001-LY的，需要把-001-LY这部分内容去掉，一个内部订单号对应多条金蝶其他出库单
            // 形如<String,List<JdOtherOutWarehouseOrder>>，key是单据编号， value是该单据编号对应的金蝶其他出库单集合
            groupedByReceiptNumber1 = jdOtherOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                    String receiptNumber = order.getJdOtherOutWarehouseOrderNumber();
                    if (receiptNumber != null && receiptNumber.contains("-")) {
                        return receiptNumber.split("-")[0];
                    }
                    return receiptNumber;
                }));
            // 第二次分组，形如Map<String,List<String>>，key是单据编号， value是该单据编号对应的金蝶其他出库单物料编码集合
            groupedByReceiptNumber2 = jdOtherOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                        String receiptNumber = order.getJdOtherOutWarehouseOrderNumber();
                        if (receiptNumber != null && receiptNumber.contains("-")) {
                            return receiptNumber.split("-")[0];
                        }
                        return receiptNumber;
                    },
                    Collectors.mapping(JdOtherOutWarehouseOrderVo::getMaterialCode, Collectors.toList())));

        }

        if (CollUtil.isNotEmpty(groupedByInnerOrderNumber2) && CollUtil.isNotEmpty(groupedByReceiptNumber2)) {
            // 3、数据比较，两次比较均以聚水潭的为准，比对出缺少的数据，组装多个Map<String, List<String>，添加进List<Map<String, List<String>>> orderMaterialMap中
            // 3-1、第一次比较，比较出金蝶不存在的内部订单号，其对应的物料编码需要去第1步中的聚水潭分组数据查询，组装多个Map<String, List<String>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            Set<String> jstInnerOrderNumbers = groupedByInnerOrderNumber1.keySet();
            Set<String> jdReceiptNumbers = groupedByReceiptNumber1.keySet();

            // 金蝶中不存在的内部订单号
            Set<String> missingInnerOrderNumbers = jstInnerOrderNumbers.stream()
                .filter(innerOrderNumber -> !jdReceiptNumbers.contains(innerOrderNumber))
                .collect(Collectors.toSet());

            for (String missingInnerOrderNumber : missingInnerOrderNumbers) {
                List<String> materialCodes = groupedByInnerOrderNumber2.get(missingInnerOrderNumber);
                if (materialCodes != null) {
                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                    missingOrderMaterialMap.put(missingInnerOrderNumber, materialCodes);
                    orderMaterialMap.add(missingOrderMaterialMap);
                }
            }

            // 3-2、第二次比较，内部订单号相同的情况下，比对缺少的物料编码，组装多个Map<String, List<String>>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            for (String innerOrderNumber : jstInnerOrderNumbers) {
                if (jdReceiptNumbers.contains(innerOrderNumber)) {
                    List<String> jstMaterialCodes = groupedByInnerOrderNumber2.get(innerOrderNumber);
                    List<String> jdMaterialCodes = groupedByReceiptNumber2.get(innerOrderNumber);

                    if (jstMaterialCodes != null && jdMaterialCodes != null) {
                        // 获取聚水潭和金蝶的日期
                        List<String> jstOrderDates = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                            .map(JstSaleOutWarehouseOrderVo::getCompareDateToJd)
                            .distinct()
                            .collect(Collectors.toList());
                        List<String> jdOrderDates = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                            .map(JdOtherOutWarehouseOrderVo::getOrderDate)
                            .distinct()
                            .collect(Collectors.toList());

                        // 比较日期
                        for (String jstOrderDate : jstOrderDates) {
                            if (!jdOrderDates.contains(jstOrderDate)) {
                                // 金蝶中不存在该日期的内部订单号
                                Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                missingOrderMaterialMap.put(innerOrderNumber, jstMaterialCodes);
                                jstOrderDateList.add(jstOrderDate);
                                orderMaterialMap.add(missingOrderMaterialMap);
                            } else {
                                // 日期相同的情况下，比对缺少的物料编码
                                List<String> jstMaterialCodesForDate = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getCompareDateToJd().equals(jstOrderDate))
                                    .map(JstSaleOutWarehouseOrderVo::getJdMaterialCode)
                                    .collect(Collectors.toList());
                                List<String> jdMaterialCodesForDate = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getOrderDate().equals(jstOrderDate))
                                    .map(JdOtherOutWarehouseOrderVo::getMaterialCode)
                                    .collect(Collectors.toList());

                                List<String> missingMaterialCodes = jstMaterialCodesForDate.stream()
                                    .filter(materialCode -> !jdMaterialCodesForDate.contains(materialCode))
                                    .collect(Collectors.toList());

                                if (!missingMaterialCodes.isEmpty()) {
                                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                    missingOrderMaterialMap.put(innerOrderNumber, missingMaterialCodes);
                                    orderMaterialMap.add(missingOrderMaterialMap);
                                }
                                jstOrderDateList.add(jstOrderDate);
                            }
                        }
                    }
                }
            }
        }
        consignmentBusinessDifferenceBo.setOrderMaterialMap(orderMaterialMap);
        consignmentBusinessDifferenceBo.setJstOrderDateList(jstOrderDateList);
        return consignmentBusinessDifferenceBo;

    }


    /**
     * 构建查询包装器（金蝶缺少的数据）
     * 场景分类：5、部门领料-网红达人店
     *
     * @param bo                              业务对象，包含查询参数
     * @param consignmentBusinessDifferenceBo 计算寄售业务差异bo对象
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopNameByJdDeficiency4(JstSaleOutWarehouseOrderBo bo,
                                                                                                    ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }

        return lqw;
    }

    /**
     * 导出聚水潭-销售出库单列表（导出5、部门领料-网红达人店的差异数据）
     *
     * @param bo
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListConsignmentBusinessDifference4(JstSaleOutWarehouseOrderBo bo) {
        // 计算5、部门领料-网红达人店业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference4();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperConsignmentBusinessDifference4(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }


    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperConsignmentBusinessDifference4(JstSaleOutWarehouseOrderBo bo, ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表（金蝶缺少的数据）
     * 场景分类：5、部门领料-展销店铺店发货
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopNameByJdDeficiency5(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算5、部门领料-展销店铺店发货场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference5();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopNameByJdDeficiency5(bo, consignmentBusinessDifferenceBo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    /**
     * 计算5、部门领料-展销店铺店场景业务差异数据
     */
    private ConsignmentBusinessDifferenceBo calculateConsignmentBusinessDifference5() {
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // List<Map<key内部订单号 value物料编码>>集合，最终组成要去查询金蝶缺少数据的条件
        List<Map<String, List<String>>> orderMaterialMap = new ArrayList<>();
        // key内部订单号 value聚水潭销售出库单集合
        Map<String, List<JstSaleOutWarehouseOrderVo>> groupedByInnerOrderNumber1 = new HashMap<>();
        // key内部订单号 value聚水潭销售出库单对应的物料编码集合
        Map<String, List<String>> groupedByInnerOrderNumber2 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单集合
        Map<String, List<JdOtherOutWarehouseOrderVo>> groupedByReceiptNumber1 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单的物料编码集合
        Map<String, List<String>> groupedByReceiptNumber2 = new HashMap<>();
        // 聚水潭日期
        Set<String> jstOrderDateList = new HashSet<>();

        // 1、查询聚水潭销售出库单，并且按照内部订单号分组
        // 一个内部订单号对应多条聚水潭销售出库单。形如<String,List<JstSaleOutWarehouseOrder>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单集合
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "展销样品店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            // 根据 innerOrderNumber 分组
            groupedByInnerOrderNumber1 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(JstSaleOutWarehouseOrderVo::getInnerOrderNumber));

            // 第二次分组，形如Map<String,List<String>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单物料编码集合
            // 根据 innerOrderNumber 分组，并提取 jdMaterialCode
            groupedByInnerOrderNumber2 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(
                    JstSaleOutWarehouseOrderVo::getInnerOrderNumber,
                    Collectors.mapping(JstSaleOutWarehouseOrderVo::getJdMaterialCode, Collectors.toList())
                ));

        }

        // 2、查询金蝶其他出库单，并且按照单据编号分组
        LambdaQueryWrapper<JdOtherOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.eq(JdOtherOutWarehouseOrder::getJdOtherOutWarehouseOrderCustomer, "展销样品店铺");
        List<JdOtherOutWarehouseOrderVo> jdOtherOutWarehouseOrderList = jdOtherOutWarehouseOrderMapper.selectVoList(lqw2);
        if (CollUtil.isNotEmpty(jdOtherOutWarehouseOrderList)) {
            // 单据编号形如2057362-001-LY的，需要把-001-LY这部分内容去掉，一个内部订单号对应多条金蝶其他出库单
            // 形如<String,List<JdOtherOutWarehouseOrder>>，key是单据编号， value是该单据编号对应的金蝶其他出库单集合
            groupedByReceiptNumber1 = jdOtherOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                    String receiptNumber = order.getJdOtherOutWarehouseOrderNumber();
                    if (receiptNumber != null && receiptNumber.contains("-")) {
                        return receiptNumber.split("-")[0];
                    }
                    return receiptNumber;
                }));
            // 第二次分组，形如Map<String,List<String>>，key是单据编号， value是该单据编号对应的金蝶其他出库单物料编码集合
            groupedByReceiptNumber2 = jdOtherOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                        String receiptNumber = order.getJdOtherOutWarehouseOrderNumber();
                        if (receiptNumber != null && receiptNumber.contains("-")) {
                            return receiptNumber.split("-")[0];
                        }
                        return receiptNumber;
                    },
                    Collectors.mapping(JdOtherOutWarehouseOrderVo::getMaterialCode, Collectors.toList())));

        }

        if (CollUtil.isNotEmpty(groupedByInnerOrderNumber2) && CollUtil.isNotEmpty(groupedByReceiptNumber2)) {
            // 3、数据比较，两次比较均以聚水潭的为准，比对出缺少的数据，组装多个Map<String, List<String>，添加进List<Map<String, List<String>>> orderMaterialMap中
            // 3-1、第一次比较，比较出金蝶不存在的内部订单号，其对应的物料编码需要去第1步中的聚水潭分组数据查询，组装多个Map<String, List<String>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            Set<String> jstInnerOrderNumbers = groupedByInnerOrderNumber1.keySet();
            Set<String> jdReceiptNumbers = groupedByReceiptNumber1.keySet();

            // 金蝶中不存在的内部订单号
            Set<String> missingInnerOrderNumbers = jstInnerOrderNumbers.stream()
                .filter(innerOrderNumber -> !jdReceiptNumbers.contains(innerOrderNumber))
                .collect(Collectors.toSet());

            for (String missingInnerOrderNumber : missingInnerOrderNumbers) {
                List<String> materialCodes = groupedByInnerOrderNumber2.get(missingInnerOrderNumber);
                if (materialCodes != null) {
                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                    missingOrderMaterialMap.put(missingInnerOrderNumber, materialCodes);
                    orderMaterialMap.add(missingOrderMaterialMap);
                }
            }

            // 3-2、第二次比较，内部订单号相同的情况下，比对缺少的物料编码，组装多个Map<String, List<String>>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            for (String innerOrderNumber : jstInnerOrderNumbers) {
                if (jdReceiptNumbers.contains(innerOrderNumber)) {
                    List<String> jstMaterialCodes = groupedByInnerOrderNumber2.get(innerOrderNumber);
                    List<String> jdMaterialCodes = groupedByReceiptNumber2.get(innerOrderNumber);

                    if (jstMaterialCodes != null && jdMaterialCodes != null) {
                        // 获取聚水潭和金蝶的日期
                        List<String> jstOrderDates = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                            .map(JstSaleOutWarehouseOrderVo::getCompareDateToJd)
                            .distinct()
                            .collect(Collectors.toList());
                        List<String> jdOrderDates = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                            .map(JdOtherOutWarehouseOrderVo::getOrderDate)
                            .distinct()
                            .collect(Collectors.toList());

                        // 比较日期
                        for (String jstOrderDate : jstOrderDates) {
                            if (!jdOrderDates.contains(jstOrderDate)) {
                                // 金蝶中不存在该日期的内部订单号
                                Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                missingOrderMaterialMap.put(innerOrderNumber, jstMaterialCodes);
                                jstOrderDateList.add(jstOrderDate);
                                orderMaterialMap.add(missingOrderMaterialMap);
                            } else {
                                // 日期相同的情况下，比对缺少的物料编码
                                List<String> jstMaterialCodesForDate = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getCompareDateToJd().equals(jstOrderDate))
                                    .map(JstSaleOutWarehouseOrderVo::getJdMaterialCode)
                                    .collect(Collectors.toList());
                                List<String> jdMaterialCodesForDate = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getOrderDate().equals(jstOrderDate))
                                    .map(JdOtherOutWarehouseOrderVo::getMaterialCode)
                                    .collect(Collectors.toList());

                                List<String> missingMaterialCodes = jstMaterialCodesForDate.stream()
                                    .filter(materialCode -> !jdMaterialCodesForDate.contains(materialCode))
                                    .collect(Collectors.toList());

                                if (!missingMaterialCodes.isEmpty()) {
                                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                    missingOrderMaterialMap.put(innerOrderNumber, missingMaterialCodes);
                                    orderMaterialMap.add(missingOrderMaterialMap);
                                }
                                jstOrderDateList.add(jstOrderDate);
                            }
                        }
                    }
                }
            }
        }
        consignmentBusinessDifferenceBo.setOrderMaterialMap(orderMaterialMap);
        consignmentBusinessDifferenceBo.setJstOrderDateList(jstOrderDateList);
        return consignmentBusinessDifferenceBo;

    }

    /**
     * 构建查询包装器（金蝶缺少的数据）
     * 场景分类：5、部门领料-展销店铺店发货
     *
     * @param bo                              业务对象，包含查询参数
     * @param consignmentBusinessDifferenceBo 计算寄售业务差异bo对象
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopNameByJdDeficiency5(JstSaleOutWarehouseOrderBo bo,
                                                                                                    ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

//            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }

        return lqw;
    }


    /**
     * 导出聚水潭-销售出库单列表（导出5、部门领料-展销店铺店发货的差异数据）
     *
     * @param bo
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListConsignmentBusinessDifference5(JstSaleOutWarehouseOrderBo bo) {
        // 计算5、部门领料-展销店铺店发货业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference5();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperConsignmentBusinessDifference5(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }


    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperConsignmentBusinessDifference5(JstSaleOutWarehouseOrderBo bo, ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

//            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }
        return lqw;
    }


    /**
     * 查询聚水潭-销售出库单列表（金蝶缺少的数据）
     * 场景分类：5、部门领料-办公店铺店发货
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopNameByJdDeficiency6(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算5、部门领料-展销店铺店发货场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference6();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopNameByJdDeficiency6(bo, consignmentBusinessDifferenceBo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    /**
     * 计算5、部门领料-办公店铺店场景业务差异数据
     */
    private ConsignmentBusinessDifferenceBo calculateConsignmentBusinessDifference6() {
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // List<Map<key内部订单号 value物料编码>>集合，最终组成要去查询金蝶缺少数据的条件
        List<Map<String, List<String>>> orderMaterialMap = new ArrayList<>();
        // key内部订单号 value聚水潭销售出库单集合
        Map<String, List<JstSaleOutWarehouseOrderVo>> groupedByInnerOrderNumber1 = new HashMap<>();
        // key内部订单号 value聚水潭销售出库单对应的物料编码集合
        Map<String, List<String>> groupedByInnerOrderNumber2 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单集合
        Map<String, List<JdOtherOutWarehouseOrderVo>> groupedByReceiptNumber1 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单的物料编码集合
        Map<String, List<String>> groupedByReceiptNumber2 = new HashMap<>();
        // 聚水潭日期
        Set<String> jstOrderDateList = new HashSet<>();

        // 1、查询聚水潭销售出库单，并且按照内部订单号分组
        // 一个内部订单号对应多条聚水潭销售出库单。形如<String,List<JstSaleOutWarehouseOrder>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单集合
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "办公室店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            // 根据 innerOrderNumber 分组
            groupedByInnerOrderNumber1 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(JstSaleOutWarehouseOrderVo::getInnerOrderNumber));

            // 第二次分组，形如Map<String,List<String>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单物料编码集合
            // 根据 innerOrderNumber 分组，并提取 jdMaterialCode
            groupedByInnerOrderNumber2 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(
                    JstSaleOutWarehouseOrderVo::getInnerOrderNumber,
                    Collectors.mapping(JstSaleOutWarehouseOrderVo::getJdMaterialCode, Collectors.toList())
                ));

        }

        // 2、查询金蝶其他出库单，并且按照单据编号分组
        LambdaQueryWrapper<JdOtherOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.eq(JdOtherOutWarehouseOrder::getJdOtherOutWarehouseOrderCustomer, "办公店铺");
        List<JdOtherOutWarehouseOrderVo> jdOtherOutWarehouseOrderList = jdOtherOutWarehouseOrderMapper.selectVoList(lqw2);
        if (CollUtil.isNotEmpty(jdOtherOutWarehouseOrderList)) {
            // 单据编号形如2057362-001-LY的，需要把-001-LY这部分内容去掉，一个内部订单号对应多条金蝶直接调拨单
            // 形如<String,List<JdOtherOutWarehouseOrder>>，key是单据编号， value是该单据编号对应的金蝶其他出库集合
            groupedByReceiptNumber1 = jdOtherOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                    String receiptNumber = order.getJdOtherOutWarehouseOrderNumber();
                    if (receiptNumber != null && receiptNumber.contains("-")) {
                        return receiptNumber.split("-")[0];
                    }
                    return receiptNumber;
                }));
            // 第二次分组，形如Map<String,List<String>>，key是单据编号， value是该单据编号对应的金蝶其他出库单物料编码集合
            groupedByReceiptNumber2 = jdOtherOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                        String receiptNumber = order.getJdOtherOutWarehouseOrderNumber();
                        if (receiptNumber != null && receiptNumber.contains("-")) {
                            return receiptNumber.split("-")[0];
                        }
                        return receiptNumber;
                    },
                    Collectors.mapping(JdOtherOutWarehouseOrderVo::getMaterialCode, Collectors.toList())));

        }

        if (CollUtil.isNotEmpty(groupedByInnerOrderNumber2) && CollUtil.isNotEmpty(groupedByReceiptNumber2)) {
            // 3、数据比较，两次比较均以聚水潭的为准，比对出缺少的数据，组装多个Map<String, List<String>，添加进List<Map<String, List<String>>> orderMaterialMap中
            // 3-1、第一次比较，比较出金蝶不存在的内部订单号，其对应的物料编码需要去第1步中的聚水潭分组数据查询，组装多个Map<String, List<String>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            Set<String> jstInnerOrderNumbers = groupedByInnerOrderNumber1.keySet();
            Set<String> jdReceiptNumbers = groupedByReceiptNumber1.keySet();

            // 金蝶中不存在的内部订单号
            Set<String> missingInnerOrderNumbers = jstInnerOrderNumbers.stream()
                .filter(innerOrderNumber -> !jdReceiptNumbers.contains(innerOrderNumber))
                .collect(Collectors.toSet());

            for (String missingInnerOrderNumber : missingInnerOrderNumbers) {
                List<String> materialCodes = groupedByInnerOrderNumber2.get(missingInnerOrderNumber);
                if (materialCodes != null) {
                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                    missingOrderMaterialMap.put(missingInnerOrderNumber, materialCodes);
                    orderMaterialMap.add(missingOrderMaterialMap);
                }
            }

            // 3-2、第二次比较，内部订单号相同的情况下，比对缺少的物料编码，组装多个Map<String, List<String>>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            for (String innerOrderNumber : jstInnerOrderNumbers) {
                if (jdReceiptNumbers.contains(innerOrderNumber)) {
                    List<String> jstMaterialCodes = groupedByInnerOrderNumber2.get(innerOrderNumber);
                    List<String> jdMaterialCodes = groupedByReceiptNumber2.get(innerOrderNumber);

                    if (jstMaterialCodes != null && jdMaterialCodes != null) {
                        // 获取聚水潭和金蝶的日期
                        List<String> jstOrderDates = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                            .map(JstSaleOutWarehouseOrderVo::getCompareDateToJd)
                            .distinct()
                            .collect(Collectors.toList());
                        List<String> jdOrderDates = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                            .map(JdOtherOutWarehouseOrderVo::getOrderDate)
                            .distinct()
                            .collect(Collectors.toList());

                        // 比较日期
                        for (String jstOrderDate : jstOrderDates) {
                            if (!jdOrderDates.contains(jstOrderDate)) {
                                // 金蝶中不存在该日期的内部订单号
                                Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                missingOrderMaterialMap.put(innerOrderNumber, jstMaterialCodes);
                                jstOrderDateList.add(jstOrderDate);
                                orderMaterialMap.add(missingOrderMaterialMap);
                            } else {
                                // 日期相同的情况下，比对缺少的物料编码
                                List<String> jstMaterialCodesForDate = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getCompareDateToJd().equals(jstOrderDate))
                                    .map(JstSaleOutWarehouseOrderVo::getJdMaterialCode)
                                    .collect(Collectors.toList());
                                List<String> jdMaterialCodesForDate = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getOrderDate().equals(jstOrderDate))
                                    .map(JdOtherOutWarehouseOrderVo::getMaterialCode)
                                    .collect(Collectors.toList());

                                List<String> missingMaterialCodes = jstMaterialCodesForDate.stream()
                                    .filter(materialCode -> !jdMaterialCodesForDate.contains(materialCode))
                                    .collect(Collectors.toList());

                                if (!missingMaterialCodes.isEmpty()) {
                                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                    missingOrderMaterialMap.put(innerOrderNumber, missingMaterialCodes);
                                    orderMaterialMap.add(missingOrderMaterialMap);
                                }
                                jstOrderDateList.add(jstOrderDate);
                            }
                        }
                    }
                }
            }
        }
        consignmentBusinessDifferenceBo.setOrderMaterialMap(orderMaterialMap);
        consignmentBusinessDifferenceBo.setJstOrderDateList(jstOrderDateList);
        return consignmentBusinessDifferenceBo;

    }


    /**
     * 构建查询包装器（金蝶缺少的数据）
     * 场景分类：5、部门领料-办公店铺店发货
     *
     * @param bo                              业务对象，包含查询参数
     * @param consignmentBusinessDifferenceBo 计算寄售业务差异bo对象
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopNameByJdDeficiency6(JstSaleOutWarehouseOrderBo bo,
                                                                                                    ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

//            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }

        return lqw;
    }


    /**
     * 导出聚水潭-销售出库单列表（导出5、部门领料-办公店铺店发货的差异数据）
     *
     * @param bo
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListConsignmentBusinessDifference6(JstSaleOutWarehouseOrderBo bo) {
        // 计算5、部门领料-办公店铺店发货业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference6();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperConsignmentBusinessDifference6(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }


    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperConsignmentBusinessDifference6(JstSaleOutWarehouseOrderBo bo, ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

//            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表（金蝶缺少的数据）
     * 场景分类：5、部门领料-研发店铺发货
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopNameByJdDeficiency7(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算5、部门领料-展销店铺店发货场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference7();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopNameByJdDeficiency7(bo, consignmentBusinessDifferenceBo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }


    /**
     * 计算5、部门领料-研发店铺场景业务差异数据
     */
    private ConsignmentBusinessDifferenceBo calculateConsignmentBusinessDifference7() {
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // List<Map<key内部订单号 value物料编码>>集合，最终组成要去查询金蝶缺少数据的条件
        List<Map<String, List<String>>> orderMaterialMap = new ArrayList<>();
        // key内部订单号 value聚水潭销售出库单集合
        Map<String, List<JstSaleOutWarehouseOrderVo>> groupedByInnerOrderNumber1 = new HashMap<>();
        // key内部订单号 value聚水潭销售出库单对应的物料编码集合
        Map<String, List<String>> groupedByInnerOrderNumber2 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单集合
        Map<String, List<JdOtherOutWarehouseOrderVo>> groupedByReceiptNumber1 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单的物料编码集合
        Map<String, List<String>> groupedByReceiptNumber2 = new HashMap<>();
        // 聚水潭日期
        Set<String> jstOrderDateList = new HashSet<>();

        // 1、查询聚水潭销售出库单，并且按照内部订单号分组
        // 一个内部订单号对应多条聚水潭销售出库单。形如<String,List<JstSaleOutWarehouseOrder>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单集合
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstSaleOutWarehouseOrder::getShopName, "研发店铺");
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            // 根据 innerOrderNumber 分组
            groupedByInnerOrderNumber1 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(JstSaleOutWarehouseOrderVo::getInnerOrderNumber));

            // 第二次分组，形如Map<String,List<String>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单物料编码集合
            // 根据 innerOrderNumber 分组，并提取 jdMaterialCode
            groupedByInnerOrderNumber2 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(
                    JstSaleOutWarehouseOrderVo::getInnerOrderNumber,
                    Collectors.mapping(JstSaleOutWarehouseOrderVo::getJdMaterialCode, Collectors.toList())
                ));

        }

        // 2、查询金蝶其他出库单，并且按照单据编号分组
        LambdaQueryWrapper<JdOtherOutWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.eq(JdOtherOutWarehouseOrder::getJdOtherOutWarehouseOrderCustomer, "研发店铺");
        List<JdOtherOutWarehouseOrderVo> jdOtherOutWarehouseOrderList = jdOtherOutWarehouseOrderMapper.selectVoList(lqw2);
        if (CollUtil.isNotEmpty(jdOtherOutWarehouseOrderList)) {
            // 单据编号形如2057362-001-LY的，需要把-001-LY这部分内容去掉，一个内部订单号对应多条金蝶直接调拨单
            // 形如<String,List<JdOtherOutWarehouseOrder>>，key是单据编号， value是该单据编号对应的金蝶其他出库集合
            groupedByReceiptNumber1 = jdOtherOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                    String receiptNumber = order.getJdOtherOutWarehouseOrderNumber();
                    if (receiptNumber != null && receiptNumber.contains("-")) {
                        return receiptNumber.split("-")[0];
                    }
                    return receiptNumber;
                }));
            // 第二次分组，形如Map<String,List<String>>，key是单据编号， value是该单据编号对应的金蝶其他出库单物料编码集合
            groupedByReceiptNumber2 = jdOtherOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                        String receiptNumber = order.getJdOtherOutWarehouseOrderNumber();
                        if (receiptNumber != null && receiptNumber.contains("-")) {
                            return receiptNumber.split("-")[0];
                        }
                        return receiptNumber;
                    },
                    Collectors.mapping(JdOtherOutWarehouseOrderVo::getMaterialCode, Collectors.toList())));

        }

        if (CollUtil.isNotEmpty(groupedByInnerOrderNumber2) && CollUtil.isNotEmpty(groupedByReceiptNumber2)) {
            // 3、数据比较，两次比较均以聚水潭的为准，比对出缺少的数据，组装多个Map<String, List<String>，添加进List<Map<String, List<String>>> orderMaterialMap中
            // 3-1、第一次比较，比较出金蝶不存在的内部订单号，其对应的物料编码需要去第1步中的聚水潭分组数据查询，组装多个Map<String, List<String>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            Set<String> jstInnerOrderNumbers = groupedByInnerOrderNumber1.keySet();
            Set<String> jdReceiptNumbers = groupedByReceiptNumber1.keySet();

            // 金蝶中不存在的内部订单号
            Set<String> missingInnerOrderNumbers = jstInnerOrderNumbers.stream()
                .filter(innerOrderNumber -> !jdReceiptNumbers.contains(innerOrderNumber))
                .collect(Collectors.toSet());

            for (String missingInnerOrderNumber : missingInnerOrderNumbers) {
                List<String> materialCodes = groupedByInnerOrderNumber2.get(missingInnerOrderNumber);
                if (materialCodes != null) {
                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                    missingOrderMaterialMap.put(missingInnerOrderNumber, materialCodes);
                    orderMaterialMap.add(missingOrderMaterialMap);
                }
            }

            // 3-2、第二次比较，内部订单号相同的情况下，比对缺少的物料编码，组装多个Map<String, List<String>>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            for (String innerOrderNumber : jstInnerOrderNumbers) {
                if (jdReceiptNumbers.contains(innerOrderNumber)) {
                    List<String> jstMaterialCodes = groupedByInnerOrderNumber2.get(innerOrderNumber);
                    List<String> jdMaterialCodes = groupedByReceiptNumber2.get(innerOrderNumber);

                    if (jstMaterialCodes != null && jdMaterialCodes != null) {
                        // 获取聚水潭和金蝶的日期
                        List<String> jstOrderDates = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                            .map(JstSaleOutWarehouseOrderVo::getCompareDateToJd)
                            .distinct()
                            .collect(Collectors.toList());
                        List<String> jdOrderDates = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                            .map(JdOtherOutWarehouseOrderVo::getOrderDate)
                            .distinct()
                            .collect(Collectors.toList());

                        // 比较日期
                        for (String jstOrderDate : jstOrderDates) {
                            if (!jdOrderDates.contains(jstOrderDate)) {
                                // 金蝶中不存在该日期的内部订单号
                                Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                missingOrderMaterialMap.put(innerOrderNumber, jstMaterialCodes);
                                jstOrderDateList.add(jstOrderDate);
                                orderMaterialMap.add(missingOrderMaterialMap);
                            } else {
                                // 日期相同的情况下，比对缺少的物料编码
                                List<String> jstMaterialCodesForDate = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getCompareDateToJd().equals(jstOrderDate))
                                    .map(JstSaleOutWarehouseOrderVo::getJdMaterialCode)
                                    .collect(Collectors.toList());
                                List<String> jdMaterialCodesForDate = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getOrderDate().equals(jstOrderDate))
                                    .map(JdOtherOutWarehouseOrderVo::getMaterialCode)
                                    .collect(Collectors.toList());

                                List<String> missingMaterialCodes = jstMaterialCodesForDate.stream()
                                    .filter(materialCode -> !jdMaterialCodesForDate.contains(materialCode))
                                    .collect(Collectors.toList());

                                if (!missingMaterialCodes.isEmpty()) {
                                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                    missingOrderMaterialMap.put(innerOrderNumber, missingMaterialCodes);
                                    orderMaterialMap.add(missingOrderMaterialMap);
                                }
                                jstOrderDateList.add(jstOrderDate);
                            }
                        }
                    }
                }
            }
        }
        consignmentBusinessDifferenceBo.setOrderMaterialMap(orderMaterialMap);
        consignmentBusinessDifferenceBo.setJstOrderDateList(jstOrderDateList);
        return consignmentBusinessDifferenceBo;

    }

    /**
     * 构建查询包装器（金蝶缺少的数据）
     * 场景分类：5、部门领料-研发店铺发货
     *
     * @param bo                              业务对象，包含查询参数
     * @param consignmentBusinessDifferenceBo 计算寄售业务差异bo对象
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopNameByJdDeficiency7(JstSaleOutWarehouseOrderBo bo,
                                                                                                    ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

//            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }

        return lqw;
    }


    /**
     * 导出聚水潭-销售出库单列表（导出5、部门领料-研发店铺的差异数据）
     *
     * @param bo
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListConsignmentBusinessDifference7(JstSaleOutWarehouseOrderBo bo) {
        // 计算5、部门领料-办公店铺店发货业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference7();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperConsignmentBusinessDifference7(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperConsignmentBusinessDifference7(JstSaleOutWarehouseOrderBo bo, ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

//            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }
        return lqw;
    }

    /**
     * 查询聚水潭-销售出库单列表（金蝶缺少的数据）
     * 场景分类：9、海外出口-海外出口（东莞仓)
     */
    @Override
    public TableDataInfo<JstSaleOutWarehouseOrderVo> queryPageListByShopNameByJdDeficiency8(JstSaleOutWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算3、寄售-寄售调拨（猫超，进口猫超，京东自营）场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference8();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperByShopNameByJdDeficiency8(bo, consignmentBusinessDifferenceBo);
        Page<JstSaleOutWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 计算9、海外出口-海外出口（东莞仓)场景业务差异数据
     */
    private ConsignmentBusinessDifferenceBo calculateConsignmentBusinessDifference8() {
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // List<Map<key内部订单号 value物料编码>>集合，最终组成要去查询金蝶缺少数据的条件
        List<Map<String, List<String>>> orderMaterialMap = new ArrayList<>();
        // key内部订单号 value聚水潭销售出库单集合
        Map<String, List<JstSaleOutWarehouseOrderVo>> groupedByInnerOrderNumber1 = new HashMap<>();
        // key内部订单号 value聚水潭销售出库单对应的物料编码集合
        Map<String, List<String>> groupedByInnerOrderNumber2 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单集合
        Map<String, List<JdDirectTransferOrderVo>> groupedByReceiptNumber1 = new HashMap<>();
        // key是单据编号， value是该单据编号对应的金蝶直接调拨单的物料编码集合
        Map<String, List<String>> groupedByReceiptNumber2 = new HashMap<>();
        // 聚水潭日期
        Set<String> jstOrderDateList = new HashSet<>();

        // 1、查询聚水潭销售出库单，并且按照内部订单号分组
        // 一个内部订单号对应多条聚水潭销售出库单。形如<String,List<JstSaleOutWarehouseOrder>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单集合
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.in(JstSaleOutWarehouseOrder::getShopName, Arrays.asList("国内货代仓店铺（分销指定）", "海外备货店铺"));
        lqw1.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        List<JstSaleOutWarehouseOrderVo> jstSaleOutWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if (CollUtil.isNotEmpty(jstSaleOutWarehouseOrderList)) {
            // 根据 innerOrderNumber 分组
            groupedByInnerOrderNumber1 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(JstSaleOutWarehouseOrderVo::getInnerOrderNumber));

            // 第二次分组，形如Map<String,List<String>>，key是内部订单号， value是该内部订单号对应的聚水潭销售出库单物料编码集合
            // 根据 innerOrderNumber 分组，并提取 jdMaterialCode
            groupedByInnerOrderNumber2 = jstSaleOutWarehouseOrderList.stream()
                .collect(Collectors.groupingBy(
                    JstSaleOutWarehouseOrderVo::getInnerOrderNumber,
                    Collectors.mapping(JstSaleOutWarehouseOrderVo::getJdMaterialCode, Collectors.toList())
                ));

        }

        // 2、查询金蝶直接调拨单，并且按照单据编号分组
        LambdaQueryWrapper<JdDirectTransferOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.in(JdDirectTransferOrder::getCustomer, Arrays.asList("海外备货店铺", "国内货代店铺"));
        List<JdDirectTransferOrderVo> jdDirectTransferOrderList = jdDirectTransferOrderMapper.selectVoList(lqw2);
        if (CollUtil.isNotEmpty(jdDirectTransferOrderList)) {
            // 单据编号形如2057362-001-JS的，需要把-001-JS这部分内容去掉，一个内部订单号对应多条金蝶直接调拨单
            // 形如<String,List<JdDirectTransferOrder>>，key是单据编号， value是该单据编号对应的金蝶直接调拨单集合
            groupedByReceiptNumber1 = jdDirectTransferOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                    String receiptNumber = order.getReceiptNumber();
                    if (receiptNumber != null && receiptNumber.contains("-")) {
                        return receiptNumber.split("-")[0];
                    }
                    return receiptNumber;
                }));
            // 第二次分组，形如Map<String,List<String>>，key是单据编号， value是该单据编号对应的金蝶直接调拨单物料编码集合
            groupedByReceiptNumber2 = jdDirectTransferOrderList.stream()
                .collect(Collectors.groupingBy(order -> {
                        String receiptNumber = order.getReceiptNumber();
                        if (receiptNumber != null && receiptNumber.contains("-")) {
                            return receiptNumber.split("-")[0];
                        }
                        return receiptNumber;
                    },
                    Collectors.mapping(JdDirectTransferOrderVo::getMaterialCode, Collectors.toList())));

        }

        if (CollUtil.isNotEmpty(groupedByInnerOrderNumber2) && CollUtil.isNotEmpty(groupedByReceiptNumber2)) {
            // 3、数据比较，两次比较均以聚水潭的为准，比对出缺少的数据，组装多个Map<String, List<String>，添加进List<Map<String, List<String>>> orderMaterialMap中
            // 3-1、第一次比较，比较出金蝶不存在的内部订单号，其对应的物料编码需要去第1步中的聚水潭分组数据查询，组装多个Map<String, List<String>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            Set<String> jstInnerOrderNumbers = groupedByInnerOrderNumber1.keySet();
            Set<String> jdReceiptNumbers = groupedByReceiptNumber1.keySet();

            // 金蝶中不存在的内部订单号
            Set<String> missingInnerOrderNumbers = jstInnerOrderNumbers.stream()
                .filter(innerOrderNumber -> !jdReceiptNumbers.contains(innerOrderNumber))
                .collect(Collectors.toSet());

            for (String missingInnerOrderNumber : missingInnerOrderNumbers) {
                List<String> materialCodes = groupedByInnerOrderNumber2.get(missingInnerOrderNumber);
                if (materialCodes != null) {
                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                    missingOrderMaterialMap.put(missingInnerOrderNumber, materialCodes);
                    orderMaterialMap.add(missingOrderMaterialMap);
                }
            }

            // 3-2、第二次比较，内部订单号相同的情况下，比对缺少的物料编码，组装多个Map<String, List<String>>
            // 最后添加进List<Map<String, List<String>>> orderMaterialMap中
            for (String innerOrderNumber : jstInnerOrderNumbers) {
                if (jdReceiptNumbers.contains(innerOrderNumber)) {
                    List<String> jstMaterialCodes = groupedByInnerOrderNumber2.get(innerOrderNumber);
                    List<String> jdMaterialCodes = groupedByReceiptNumber2.get(innerOrderNumber);

                    if (jstMaterialCodes != null && jdMaterialCodes != null) {
                        // 获取聚水潭和金蝶的日期
                        List<String> jstOrderDates = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                            .map(JstSaleOutWarehouseOrderVo::getCompareDateToJd)
                            .distinct()
                            .collect(Collectors.toList());
                        List<String> jdOrderDates = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                            .map(JdDirectTransferOrderVo::getReceiptDate)
                            .distinct()
                            .collect(Collectors.toList());

                        // 比较日期
                        for (String jstOrderDate : jstOrderDates) {
                            if (!jdOrderDates.contains(jstOrderDate)) {
                                // 金蝶中不存在该日期的内部订单号
                                Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                missingOrderMaterialMap.put(innerOrderNumber, jstMaterialCodes);
                                jstOrderDateList.add(jstOrderDate);
                                orderMaterialMap.add(missingOrderMaterialMap);
                            } else {
                                // 日期相同的情况下，比对缺少的物料编码
                                List<String> jstMaterialCodesForDate = groupedByInnerOrderNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getCompareDateToJd().equals(jstOrderDate))
                                    .map(JstSaleOutWarehouseOrderVo::getJdMaterialCode)
                                    .collect(Collectors.toList());
                                List<String> jdMaterialCodesForDate = groupedByReceiptNumber1.get(innerOrderNumber).stream()
                                    .filter(order -> order.getReceiptDate().equals(jstOrderDate))
                                    .map(JdDirectTransferOrderVo::getMaterialCode)
                                    .collect(Collectors.toList());

                                List<String> missingMaterialCodes = jstMaterialCodesForDate.stream()
                                    .filter(materialCode -> !jdMaterialCodesForDate.contains(materialCode))
                                    .collect(Collectors.toList());

                                if (!missingMaterialCodes.isEmpty()) {
                                    Map<String, List<String>> missingOrderMaterialMap = new HashMap<>();
                                    missingOrderMaterialMap.put(innerOrderNumber, missingMaterialCodes);
                                    orderMaterialMap.add(missingOrderMaterialMap);
                                }
                                jstOrderDateList.add(jstOrderDate);
                            }
                        }
                    }
                }
            }
        }
        consignmentBusinessDifferenceBo.setOrderMaterialMap(orderMaterialMap);
        consignmentBusinessDifferenceBo.setJstOrderDateList(jstOrderDateList);
        return consignmentBusinessDifferenceBo;

    }

    /**
     * 构建查询包装器（金蝶缺少的数据）
     * 场景分类：9、海外出口-海外出口（东莞仓)
     *
     * @param bo                              业务对象，包含查询参数
     * @param consignmentBusinessDifferenceBo 计算寄售业务差异bo对象
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperByShopNameByJdDeficiency8(JstSaleOutWarehouseOrderBo bo,
                                                                                                    ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 店铺名称集合
        lqw.in(CollUtil.isNotEmpty(bo.getShopNameList()), JstSaleOutWarehouseOrder::getShopName, bo.getShopNameList());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            // 拿有差异的单号和物料编码
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

            // 拿有差异的日期查询
//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }

        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }


        return lqw;
    }

    /**
     * 查询符合条件的聚水潭-销售出库单列表（9、海外出口-海外出口（东莞仓)）的差异数据）
     *
     * @param bo 查询条件
     * @return 聚水潭-销售出库单列表
     */
    @Override
    public List<JstSaleOutWarehouseOrderVo> queryListConsignmentBusinessDifference8(JstSaleOutWarehouseOrderBo bo) {
        // 计算3、寄售-寄售调拨（猫超，进口猫超，京东自营）场景业务差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculateConsignmentBusinessDifference8();
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = buildQueryWrapperConsignmentBusinessDifference8(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }


    /**
     * 构建查询包装器
     *
     * @param bo 业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     */
    private LambdaQueryWrapper<JstSaleOutWarehouseOrder> buildQueryWrapperConsignmentBusinessDifference8(JstSaleOutWarehouseOrderBo bo, ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstSaleOutWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundDeliveryOrderNumber()), JstSaleOutWarehouseOrder::getOutboundDeliveryOrderNumber, bo.getOutboundDeliveryOrderNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getShopNumber()), JstSaleOutWarehouseOrder::getShopNumber, bo.getShopNumber());
        // 对店铺名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstSaleOutWarehouseOrder::getShopName, bo.getShopName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getInnerOrderNumber()), JstSaleOutWarehouseOrder::getInnerOrderNumber, bo.getInnerOrderNumber());
        // 对出库日期进行精确查询
        lqw.eq(bo.getOutboundDeliveryDate() != null, JstSaleOutWarehouseOrder::getOutboundDeliveryDate, bo.getOutboundDeliveryDate());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getOutboundStatus()), JstSaleOutWarehouseOrder::getOutboundStatus, bo.getOutboundStatus());
        // 对产品名称使用like模糊查询
        lqw.like(StringUtils.isNotBlank(bo.getProductName()), JstSaleOutWarehouseOrder::getProductName, bo.getProductName());
        // 添加非空且非blank的查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getWarehouse()), JstSaleOutWarehouseOrder::getWarehouse, bo.getWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstSaleOutWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstSaleOutWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getJdMaterialCode()), JstSaleOutWarehouseOrder::getJdMaterialCode, bo.getJdMaterialCode());
        // 对标准颜色SKU进行精确查询
        lqw.eq(StringUtils.isNotBlank(bo.getStandardColorSku()), JstSaleOutWarehouseOrder::getStandardColorSku, bo.getStandardColorSku());
        lqw.eq(JstSaleOutWarehouseOrder::getDataSign, "0");
        // 添加非空的查询条件
        lqw.eq(bo.getQuantity() != null, JstSaleOutWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstSaleOutWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstSaleOutWarehouseOrder::getId, idsList);
        }

        // 根据内部订单号和物料编码查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getOrderMaterialMap()) && !boParams) {
            Map<String, List<String>> orderMaterialMap = consignmentBusinessDifferenceBo.getOrderMaterialMap().stream()
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())))
                .entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                    entry -> entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : orderMaterialMap.entrySet()) {
                String innerOrderNumber = entry.getKey();
                List<String> jdMaterialCodes = entry.getValue();
                lqw.or(i -> i.eq(JstSaleOutWarehouseOrder::getInnerOrderNumber, innerOrderNumber)
                    .in(JstSaleOutWarehouseOrder::getJdMaterialCode, jdMaterialCodes));
            }

//            if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getJstOrderDateList())) {
//                lqw.and(i -> i.in(JstSaleOutWarehouseOrder::getCompareDateToJd, consignmentBusinessDifferenceBo.getJstOrderDateList()));
//            }
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.eq(JstSaleOutWarehouseOrder::getCompareDateToJd, 0);
        }
        return lqw;
    }



    /**
     * 判断任意一个参数值是否不为空
     *
     * @param bo 要检查的 JstSaleOutWarehouseOrderBo 对象
     * @return 如果任意一个参数值不为空，则返回 true，否则返回 false
     */
    public boolean isAnyFieldNonEmpty(JstSaleOutWarehouseOrderBo bo) {
        return bo.getId() != null ||
            (bo.getIds() != null && !bo.getIds().isEmpty()) ||
            (bo.getOutboundDeliveryOrderNumber() != null && !bo.getOutboundDeliveryOrderNumber().isEmpty()) ||
            (bo.getShopNumber() != null && !bo.getShopNumber().isEmpty()) ||
            (bo.getShopName() != null && !bo.getShopName().isEmpty()) ||
            (bo.getInnerOrderNumber() != null && !bo.getInnerOrderNumber().isEmpty()) ||
            bo.getOutboundDeliveryDate() != null ||
            (bo.getOutboundDeliveryDateNew() != null && !bo.getOutboundDeliveryDateNew().isEmpty()) ||
            (bo.getOutboundStatus() != null && !bo.getOutboundStatus().isEmpty()) ||
            (bo.getProductName() != null && !bo.getProductName().isEmpty()) ||
            (bo.getWarehouse() != null && !bo.getWarehouse().isEmpty()) ||
            (bo.getStyleNumber() != null && !bo.getStyleNumber().isEmpty()) ||
            (bo.getProductNumber() != null && !bo.getProductNumber().isEmpty()) ||
            (bo.getJdMaterialCode() != null && !bo.getJdMaterialCode().isEmpty()) ||
            (bo.getStandardColorSku() != null && !bo.getStandardColorSku().isEmpty()) ||
            bo.getQuantity() != null ||
            (bo.getShopNameList() != null && !bo.getShopNameList().isEmpty()) ||
            bo.getNewOrderDate() != null ||
            (bo.getCompareDateToJd() != null && !bo.getCompareDateToJd().isEmpty());
    }




}
